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.





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?
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.
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
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?
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
Yes, I’ll check it out. Sadly dealing with fonts does seem to be overly complicated.
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
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.