Getting Through Black Magic: Font Embedding

Be it in Fx2, Fx3 or Fx4, Font Embedding is an integral part of any application due to the annoying issues you will start running into by just using device fonts. And once you get your embedded font into the application you’ll never look back at the issue, but getting the embedded font into the application seems bring some developers to their knees.

There are two main ways that I see people embed fonts.

1) Straight @font-face embed via Flex CSS
2) Embedding the font into a Flash File, selecting the glyphs to embed, and then embedding the resulting SWF into Flex.

People use the first one for simplicity and the second (definitely more difficult route) for optimization. Yet people keep forgetting (or never knew) that there is a third route that provides simplicity and optimization.

First, the basics…
In your Flex CSS file (or in the style block) start up a new font face block.

1
2
@font-face {
}

Next provide a direct path from your application’s root folder to the font. For ease I usually make a copy of the font and stick it in my assets folder so that other people connected to my project can still build the app.

1
2
3
@font-face {
     src: url("/assets/fonts/verdana.ttf");
}

Now name the new font-face so it can be referenced as a font family.

1
2
3
4
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
}

Next you need to add some description to the font. Is it a normal font?

1
2
3
4
5
6
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: normal;
}

Bold?

1
2
3
4
5
6
@font-face {
     src: url("/assets/fonts/verdanab.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: bold;
}

Italic?

1
2
3
4
5
6
@font-face {
     src: url("/assets/fonts/verdanai.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: italic;
     fontWeight: normal;
}

Bold and Italic?

1
2
3
4
5
6
@font-face {
     src: url("/assets/fonts/verdanaz.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: italic;
     fontWeight: bold;
}

To have all four of these options you would need to embed each of the different fonts that include all these options. They can all be under the same fontFamily name, but with different configurations. But if you are missing the bold font and trying to make your text bold you will not be getting the desired look.

If you are confused at all by the different @font-face blocks below make sure to look at the actually font file name. You will notice each is just slightly different with the different look.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: normal;
}

@font-face {
     src: url("/assets/fonts/verdanab.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: bold;
}

@font-face {
     src: url("/assets/fonts/verdanai.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: italic;
     fontWeight: normal;
}

@font-face {
     src: url("/assets/fonts/verdanaz.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: italic;
     fontWeight: bold;
}

Next you need to set whether your font is using advanced anti aliasing. This takes slightly more processing, but can make your fonts look nicer at larger sizes. This is dependent also on whether the font type supports it. Usually, I just set this to true.

1
2
3
4
5
6
7
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: normal;
     advancedAntiAliasing: true;
}

Now with Fx4 you have something new to worry about: CFF. If this is set to true, the font will be available to the new TLF engine and Fx4 (Spark) components. If CFF is set to false then it will be available to Fx3 (Halo) components. Yes, right now you need to embed two fonts to get this to work for both. In the future this may change.

1
2
3
4
5
6
7
8
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: normal;
     advancedAntiAliasing: true;
     cff: true
}

And now, the optimization…
You may have hit some issues with all the previous steps, or not – but here is the optimizations. Within the @font-face tag you can set which unicode characters to embed – this is like selecting the glyphs in Flash. To find a helpful table of common unicode characters and ranges that people use refer back to your flex sdk, specifically: flex-sdk-folder/frameworks/flash-unicode-table.xml. After looking through the table you can select your desired ranges that you want included with the font embed. The more unicode characters the larger the final SWF file will be, the fewer, the smaller.
My final @font-face embed statement.

1
2
3
4
5
6
7
8
9
10
11
12
13
@font-face {
     src: url("/assets/fonts/verdana.ttf");
     fontFamily: verdanaEmbed;
     fontStyle: normal;
     fontWeight: normal;
     advancedAntiAliasing: true;
     cff: true
     unicodeRange:
           U+0041-U+005A, /* Upper-Case [A..Z] */
           U+0061-U+007A, /* Lower-Case a-z */
           U+0030-U+0039, /* Numbers [0..9] */
           U+0020-U+002F,U+003A-U+0040,U+005B-U+0060,U+007B-U+007E; /* Puctuation */
}

Profit!
That’s it, embedded and optimized fonts. I’ve actually tested the size of the resulting Flex App SWF files after going the long route and the route shown here. Both resulting sizes are exactly the same, down to the last byte.

  • Share/Bookmark

Comments (8)

BillNovember 24th, 2009 at 11:25 am

So you have to have 4 separate versions of the Verdana font – one for each style and weight combination? Last time I checked the standard Verdana font came as a single TTF file. How do you break it out into separate normal, bold, italic, and italic bold versions?

Jonathan CamposNovember 24th, 2009 at 11:34 am

Though explorers just show one the actual files are split into each different type. Check out your actual Font folder and you’ll see what I mean. Some fonts have a dozen some odd styles including all the different weights and condensed and whatnot.

PatrickDecember 4th, 2009 at 2:48 pm

Jonathan, have you been able to do this with the Flex 4 SDK? I have a SWC which used a defaults.css file to set up styling and font embedding for some custom components. When I use Flex 4 SDK and attempt to pull that SWC into another application, the fonts cannot be transcoded. I had to put the files in the final application in order to get it to build.

This exact thing worked perfectly in Flex 3 SDK!

No replies yet on the Adobe forum either: http://forums.adobe.com/thread/534070?tstart=0

Have you run into this, or have you been able to use CSS in SWC’s to embed fonts?

Thanks!
Patrick

Jonathan CamposDecember 4th, 2009 at 2:51 pm

I haven’t tried putting fonts into swcs via css. Usually I create a new css for each app since that will be unique to the app. Have you made sure that your font files are included the swc as an embedded asset?

PatrickDecember 4th, 2009 at 2:57 pm

The exact same SC had been working for months built with 3.4 SDK. I did check the Assets tab to ensure the fonts were included. I know FB is seeing them as the error changes from “Unable to resolve for transcoding” as opposed to “unable to read transcoding source” when the file is there and added to the library as an asset.

Oddly, this same thing works for me using the Fx 4 SDK at the command line, building the SWC with compc with include directives for the CSS and fonts.

There is a zip file with some test projects in the aforementioned Adobe forum post if you’re interested in giving it a try in your FB4 environment.

I can’t believe something so simple is causing so much trouble!

Cheers,
-Patrick

Jonathan CamposDecember 4th, 2009 at 3:03 pm

Yes, I’ll check it out. Sadly dealing with fonts does seem to be overly complicated.

PatrickDecember 4th, 2009 at 3:13 pm

They now acknowledge this as a bug in the SDK. I have been asked to log it, if you’re interested in watching the progress:
https://bugs.adobe.com/jira/browse/SDK-24555

Thanks for your help!
-Patrick

Jonathan CamposDecember 4th, 2009 at 3:15 pm

Watching now. Whenever you see something weird, especially in Fx4 just make sure to log it and log it well so that it can be fixed by release.

Leave a comment

Your comment