Flash: Runtime Font Sharing Embedding with only Partial Character sets: How To.

by troy on September 12, 2008

While not planning on it, spent most the day figuring out how to implement runtime shared fonts, while only embedding a fraction off the characters. Holy moly was this a minefield. But happily got a simple solution.

Here's the goal, I'm working on the phase 2.x of a web based application that uses several flavors of a stylish font. However with each flavor weighing in at ~35Kb each we are loading about 200K worth of fonts (bold, italic, bold italic etc), and at present many of the pages have their own copies of the fonts (the typical evil that comes up on projects with no time), so the sight loads far more sluggish than it should. After this and the following are done, the load is down to 54kb, as only the elements needed are loaded once.

In Flash IDE (CS3) and prior selecting partial characters was easy if you only had one swf, just select from the characters in the embed button, in the properties panel. If you have character sets you use often, short cut this by creating custom character sets, with this neat approach, perhaps even with this tool However this is only really good for elements scoped inside the swf with the embedded font, no way to share them between swfs without resorting to traditional runtime shared libraries that have several issues (like bypassing preloaders all together). In AS2.0 there was a nifty hack possible to help,where a embedded font was coerced into sharing by a proxy clip that referenced it as a runtime shared library, at the preloaders convenience, but this (for me) was brittle in having font collisions, e.g. a static textfield on stage having the same font, could render the approach useless (like the font wouln't show up at all!), and AS3 has the exact same issue.

Fflash player appears to load a font in a given swf scope on a first come-first serve only once. Meaning any static or textfield anywhere on the stage (regardless or not if any characters are embedded) will collide with whatever you load in dynamically later, rendering the dynamically loaded useless,...and any references to it. Meaning your dynamic textfields will break...not show up at all!. A possible workaround is having either the placeholder textfields with a sacrificial font (e.g. sans), or renaming the font in the embed created in a few steps to something like (Myriad Pro ->MyriadPro) and adjusting the css/etc.

For reasons unknown to me, adding a Font symbol to the library (either for use with actioncript, or runtime sharing) embeds the whole font.  Needless to say, when on the web, getting every character known to mankind is not going to help your site load fast. This can be the difference of 2kb for only what you need for the preloader, to 2MB for entire international character sets. Also it can grind compile times to a halt, as every publish requires every glyph to be embedded and this is time consuming. Both seem like major oversights on the Flash IDE's design.

So oddly the best way to create fonts is to use the Flex 3.x SDK (download). For this the great and free FlashDevelop (download) will work great (if your on windows).  Just follow the installation instructions, setup a new Actionscript 3, Flex 3 Project.

Create a class like the following in the 'src' directory, and in the righthand tree, right click over it and select 'always compile'

 package {  
      import flash.display.Sprite;
   	  import flash.text.Font;
      public class MyriadProFontLib extends Sprite {  
           [Embed(source='C:/WINDOWS/Fonts/MyriadPro-Regular.otf', fontName='Myriad Pro', unicodeRange='U+0020-U+0020,U+0021-U+0021,U+0022-U+0022,U+0023-U+0023,U+0024-U+0024,U+0025-U+0025,U+0026-U+0026,U+0027-U+0027,U+0028-U+0028,U+0029-U+0029,U+002A-U+002A,U+002B-U+002B,U+002C-U+002C,U+002D-U+002D,U+002E-U+002E,U+002F-U+002F,U+0030-U+0030,U+0031-U+0031,U+0032-U+0032,U+0033-U+0033,U+0034-U+0034,U+0035-U+0035,U+0036-U+0036,U+0037-U+0037,U+0038-U+0038,U+0039-U+0039,U+003A-U+003A,U+003B-U+003B,U+003C-U+003C,U+003D-U+003D,U+003E-U+003E,U+003F-U+003F,U+0040-U+0040,U+0041-U+0041,U+0042-U+0042,U+0043-U+0043,U+0044-U+0044,U+0045-U+0045,U+0046-U+0046,U+0047-U+0047,U+0048-U+0048,U+0049-U+0049,U+004A-U+004A,U+004B-U+004B,U+004C-U+004C,U+004D-U+004D,U+004E-U+004E,U+004F-U+004F,U+0050-U+0050,U+0051-U+0051,U+0052-U+0052,U+0053-U+0053,U+0054-U+0054,U+0055-U+0055,U+0056-U+0056,U+0057-U+0057,U+0058-U+0058,U+0059-U+0059,U+005A-U+005A,U+005B-U+005B,U+005C-U+005C,U+005D-U+005D,U+005E-U+005E,U+005F-U+005F,U+0060-U+0060,U+0061-U+0061,U+0062-U+0062,U+0063-U+0063,U+0064-U+0064,U+0065-U+0065,U+0066-U+0066,U+0067-U+0067,U+0068-U+0068,U+0069-U+0069,U+006A-U+006A,U+006B-U+006B,U+006C-U+006C,U+006D-U+006D,U+006E-U+006E,U+006F-U+006F,U+0070-U+0070,U+0071-U+0071,U+0072-U+0072,U+0073-U+0073,U+0074-U+0074,U+0075-U+0075,U+0076-U+0076,U+0077-U+0077,U+0078-U+0078,U+0079-U+0079,U+007A-U+007A,U+007B-U+007B,U+007C-U+007C,U+007D-U+007D,U+007E-U+007E,U+00A9-U+00A9,U+00AE-U+00AE,U+00B7-U+00B7,U+02C6-U+02C6,U+02DC-U+02DC,U+2013-U+2013,U+2014-U+2014,U+2018-U+2018,U+2019-U+2019,U+201A-U+201A,U+201C-U+201C,U+201D-U+201D,U+201E-U+201E,U+2020-U+2020,U+2021-U+2021,U+2022-U+2022,U+2026-U+2026,U+2030-U+2030,U+2039-U+2039,U+203A-U+203A,U+20AC-U+20AC,U+2122-U+2122')]  
            public static var _MyriadPro:Class;  
			public function MyriadProFontLib()

Go to the Top Nav's "Project>Properties" and adjust the output file to something like "bin\FontLibs.swf"

Copy the characters you want as Ascii e.g. (missing white space)

goto this great unicode converter here

top left 'characters' box, then hit convert

select the output from the Unicode U+hex notation box, and paste it into this app's left side.
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Copy the right side and replace the 'unicodeRange=''' in the above class.
In the text box next to the green play looking button make sure that the build text mode says "Release" instead of "Test" or "Debug". Then build the file by pressing the green play looking button. If all goes well you should see the console output

Build succeeded
Done (0)

and a new FontLibs.swf in the bin folder.

If you don't select Release you will get issues on older versions of the Flash 9(around 9.014) player asking users the locations of the Flash debugger, Not good.

You can use the excellent Action Script Viewer 6 to look at the glyphs embedded into the FontLibs.swf. This is very useful for seeing if the unicode is getting you the characters you think you are putting in. I tried several ascii to unicode convertors, and only the one linked above got it right.

Then using the tool of your choice create this class to load up the fontlib and use a dynamic textfield.

 package {  
      import flash.display.Loader;  
      import flash.display.Sprite;  
      import flash.events.Event;  
      import flash.net.URLRequest;  
      import flash.text.*;
	import flash.utils.describeType;
      public class FontLoader extends Sprite {  
           public function FontLoader() {  
           private function loadFont(url:String):void {  
                var loader:Loader = new Loader();  
                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, fontLoaded);  
                loader.load(new URLRequest(url));  
           private function fontLoaded(event:Event):void {  
           public function drawText():void {  
                var tf:TextField = new TextField();  
                tf.defaultTextFormat = new TextFormat("Myriad Pro", 16, 0);  
				tf.embedFonts = true;  
              tf.antiAliasType = AntiAliasType.ADVANCED;  
                tf.autoSize = TextFieldAutoSize.LEFT;  
                tf.border = true;
                tf.text = "Troy was here\nScott was here too\nblah scott...:;*&amp;^% ";
                tf.rotation = 15;

At this point you might also like to know how to embed multiple fonts into a single library for that see this post.

In decreasing order of relevance, these are some of the posts that I read to get to this point.

If characters that are embedded are funky, and your using Flex 2.0, upgrade to Flex SDK 3.x. I was originally using Flex 2.0...very dated at this point.

If your using OTF (Open Type Fonts) like Myriad Pro make sure your using Flex SDK 3.x else you might have issues...flex 2.0 is very dated at this point. Also consider using a tool like the excellent CrossFont if you're trying to use Mac Fonts.

[1] The one that helped me realize the ability to limit the unicode. The more readable one on the yahoo labs, and the authors blog with many comments. The solution he and others presented didn't work for me, and I think the solution here is cleaner.

[2] Flex 3.x Compiler comes with multiple The font transcoder doesn't always work, try another. in particular the (flash.fonts.AFEFontManager);

[3] Runtime Font Sharing For Flash CS3...[Robert's excellent article and followup] [far more verbose] , using the traditional whole-enchilada Font.

[4] Special considerations when using Japanese character sets (a) using (b)

[5] A must read if you want a grand Q&A of embedded fonts and many quirks, (CSS specific)

[6] More details on mime-type for the font, I think this was only relevant in Flex 2.0 than Flex 3.x.

[7 ] Basics with AS3/Flex without using a library

[ 8 ] More rants on Flash CS3's lack of proper embedding, in particular with pixel fonts..Flash CS3 renames them for you.

{ 9 comments… read them below or add one }

saran October 18, 2008 at 2:14 am

You can specify a range of characters instead of individual character like:


(A-Z and a-z)

dtk November 20, 2008 at 3:20 pm

I have perhaps a more simple way to reduce the file size that does not use Flex. I used FontLab (any font editor should work though) to open the font I wanted to use as my runtime font and then deleted all the extra characters I did not want. I made sure that NAME of the font was different (File -> Font Info… >> Names and Copyright). I exported the (File ->Generate Font…) as a True Type Font .ttf with a new name and the following options:

Make PFM on
Make AFM on
Always Standard Encoding
Open Type 1 export Terminal… unchecked
Use Unicode indexes as a base for TrueType Encoding … unchecked
Put MS char set value into fsSelection field… unchecked

those settings seemed to get the smallest file for me. After installing the new font and selecting it in flash as a runtime embedded font it turned out to be much smaller than the original font and smaller than doing equivalent thing using flex. here are the stats (from flash’s generate size report option in publish settings):

original size of font: 18,158 bytes

size of modified font: 9,329 bytes*

size of swf file generated with Flex with the same char set as the modified font: 10,583 bytes

*even though the size report did not show any changes in the characters exported, the size is much smaller.

Col. Kurtz January 26, 2009 at 10:56 am
c++ February 28, 2009 at 3:58 pm

I did use your technique, thanks for the article, this is much appreciated.
The only problem I encountered is that where kerning worked fine

var format:TextFormat=text.getTextFormat();

it will not work anymore after using a font library like the one shown above.
Is this inevitably so or am I missing something here?

ferdy May 26, 2009 at 4:07 pm

thanks ! that helped !

Scott June 24, 2009 at 1:49 pm

Will this Flex solution only work when the font is loaded into AS 3 Flash projects or can the FontLoader functionality be replicated in AS2?

troy June 24, 2009 at 4:26 pm

The solution here is only for AS3. You can do something similar in AS2, but it’s a bit on the complicated brittle side. Hope these will help.


fatih July 13, 2009 at 5:26 am


firstly thanks for your tutorial. I tried your tutorial but i couldnt embed some characters like “ÄŸ Äž ı Ä°”, is there any way to do this?

troy July 14, 2009 at 11:37 am

Hi fatih,

Unfortunately I don’t have an answer for you, the characters you posted don’t show up properly on my end. It might be there are not being specified with proper Unicode, or that the font library you are using can’t be embedded into the flash file. When you embed the whole font library does it work?

Leave a Comment


{ 1 trackback }

Previous post:

Next post: