Operating with embedded graphics and fonts of flash application during development is significant, since unique cross-browser (and cross-platform hopefully) look is one of key RIA/flashgame features. This article reviews font embedding for pure AS3 project, as it's the most universal way for embedding. Flashplayer uses device fonts for textfields by default. So if you specify the font property of TextFormat object, then the given font must be available on device where flash-application is running. If the preferable font is missing, default system font is used. You should embed the font to assure the font is displayed properly on any computer. Embedding gives some more advantages: font symbols can be rotated, fonts provide smoother playback when zooming, fonts are anti-aliased. The following font file types are supported by Mxmlc compiler for embedding:

  • TrueType fonts (*.ttf);
  • OpenType fonts (*.otf);
  • TrueType Collections (*.ttc);
  • Mac Data Fork Fonts (*.dfont);
  • Mac Resource Fork TrueType Suitcases (don't have file extension).

The basic syntax for font embedding is (note that semicolon is not placed at the end of line):

[Embed(source="pathToTtfFile", fontName="FontName", mimeType="application/x-font- truetype")]

You must specify either a valid URI to the font (as shown above), or reffer to the font by its name using this syntax:

[Embed(systemFont="systemName", fontName="FontName", mimeType="application/x-font")]
private static var font:Class;

The font name specified above should match the font name within the operating system. This way you do not include the font file's extension. You can embed fonts that are locally accessible by JRE, including fonts that are made available to the JRE by OS, files in the jre/lib/fonts folder and fonts that are mapped in the jre/lib/font.properties file.

For each font embedding separate metadata tag [Embed] must be defined. If you attempt to embed a font that Flex compiler cannot find, compiler throws a similar error: "exception during transcoding: Font for alias 'Tahoma' with plain weight and style was not found by family name 'Tahom'".

There are two code areas in ActionScript file where the [Embed] tag can be put:
1. Inside a package, but outside of the class definition. However this type of embedding allows you to embed only one font per file - not the best choice for rich applications. Attempt to include several embeddings in this manner will lead compiler to the error: "Unable to transcode /fontPath/FontName".
2. Inside class definition. This way you need to put Class-type or String-type variable definition right after metadata tag:

[Embed(source="pathToTtfFile", fontName="FontName", mimeType="application/x-font- truetype")]
private static var fontName:Class;

This variable is not used directly in code (though it is used to handle other embeddable data types, like images and sound). In our case this definition must exist in order the compiler to link-in the font. Compiler generates an error if no definition found: "Embed only supported with variables of type Class or String".

When dealing with fonts the [Embed] tag may take the following properties:

Name Description Acceptable values Default value
systemFont Exact name of the font installed on your system. Use either this or source parameter. String name of the font, e.g. "Arial" -
source Relative or absolute path to the font file. path string, e.g. "./font/MyriadPro-Regular.otf" -
fontName String used to identify font further in code and at runtime. Use the same string when assigning font property of TextFormat object (classic text), or fontName property of FontDesctiption object (FTE). Any string identifier -
fontFamily Property is intended to identify the precise font face. When embedding system-font this property should include the font name and font face. For example "Trebuchet MS Bold", where the font name is "Trebuchet MS" and font face is "Bold". In this case the fontName property is generated automatically.
See source code below lines 60-67. 221-238. See also Embedding multiple typafaces from container file formats below.
When embedding via source path this property becomes equivalent to the fontName property. So you may use either this, or the fontName property.
Any string identifier of the font. -
unicodeRange Unicode range for embeddable font. Specifying this range helps to reduce the size of the embedded font. Also it lets developer to embed only the glyphs that are really needed. Range syntax:
U+[beginning of range]-[end of range]
Multiple ranges are separated by commas, also single character codes are allowed. To specify required range quickly you may use Unicode range generator utility.
Ranges can be specified by names in flex-config.xml file (located at Adobe Flash Builder 4/sdks/4.0.0/frameworks/). The file contains <languages> tag, for setting up ranges. The flash-unicode-table.xml file(located at the same folder) already contains a number of pre-defined unicode table mappings, like Uppercase, Lowercase, Numerals, Punctuation, Basic Latin, Cyrillic, Arabic and others. All you need to do is paste them into flex-config.xml. When ranges specified it is handy to use their string-names. More about ranges on adobe. Y
Unicode characters in U+hex notation. Example: "U+0400-04CE, U+2000-206F, U+20A0-20CF, U+2100-2183, U+0020".
Or string names of language-ranges (the ranges must be defined in flex-config.xml). Example: "englishRange"
all glyphs of the font, but not more than 1000 per type face.
max-glyphs-per-face value can be modified in flex-config.xml file
advancedAntiAliasing Property determines whether to include advanced anti-aliasing information when embedding the font. Advanced antialiasing helps to display text clearer on small font sizes. Property is ignored when embedAsCFF property is set to true, since the Flash Text Engine (FTE) renders text by its own way. true or false true
embedAsCFF New Flash Text Engine (FTE) uses Compact Font Format (CFF) fonts. Since Flex 4 embedAsCFF is set to true by default. Classic TextFormat objects are unable to use CFF fonts. true or false true
fontWeight Property sets the type-face value of the font. Property should be used only when required for embeddable font. normal, bold, heavy normal
fontStyle Property sets the type-face value of the font. Property should be used only when required for embeddable font. normal, italic, oblique normal
mimeType This property is required if font has no, or uses untypical file extension. application/x-font, application/x-font-truetype, application/x-font-opentype, application/x-font-truetype-collection -

Embedding multiple typafaces from container file formats (.ttc, .dfont).

The documentation claims that for a "container" of several fonts (such as a *.ttc or *.dfont file), you should use the fontFamily property to select custom font face out of the collection. But this feature doesn't seem to work properly, only four basic typefaces (regular, bold, italic, bold-italic) can be embedded this way, while other typefaces like "condensed", "black", "condensed extrabold", etc. are being skipped by flex font-managers. If the typeface doesn't match 4 standard face patterns regular typeface is embedded.

To workaround this issue you may convert single font file to separate *.ttf or *.otf files. You are free to choose any converter, I'd recommend free-online converter http://onlinefontconverter.com, which worked perfectly for me on *.ttc to *.ttf conversion. Given that the subfamily for converted font doesn't match the four-standard faces, you'll have to reference that font by its name only, though it doesn't take a lot of annoyance.

Embedding bitmap fonts.

As a big fan of bitmap fonts I disable smoothing for small text sizes, if possible. Flex does not allow to disable font antialiasing, so the font is always smoothed. The best way to avoid smoothing on small sizes is to embed pixel fonts. These fonts are designed to provide crisp screen text at very small sizes, these fonts look sharp when their X and Y points are set to non-fraction values. It is also possible to create pixel bitmap font in Flash IDE, as it has the option "Bitmap text (no-antialiasing)" for text fields, publish swf with the font, and than embed it to pure as3 project. To embed bitmap font perform the following:
A) In Flash IDE:

  1. Create a new document (FLA file, AS3);
  2. Add dynamic or input text field on stage, specify the font, select "Bitmap text (no-antialiasing)" item of "Anti-alias" list;
  3. Embed font-glyphs by clicking on "Embed..." button, or type required symbols in the textfield;
  4. Convert textfield to MovieClip, select "Export for ActionScript" in "Convert to symbol" dialog, set Identifier field value;
  5. After the symbol created, publish document.

B) Than in AS3-editor (Flash Builder or whatever) embed movieclip symbol from obtained swf file:

// dentifierName is Movieclip AS3 Identifier value
[Embed(source="mySWF.swf#identifierName")]
private var MyFontHolder:Class;

The compiler will link the font from the movieclip. Note that flash automatically renames bitmap font adding suffix _9pt_st to its name, where 9 is its point size, see source code line 241.

Running example:

This movie requires Flash Player 9

Source code, concluding written above:

package
{
import flash.display.GradientType;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.geom.Matrix;
import flash.text.AntiAliasType;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.engine.*;

[SWF(width="760", height="450", frameRate="12", backgroundColor="#FFFFFF")]
public class FontTest extends Sprite {
	//Embed single font typeface from ttf file, 
	//advancedAntialiasing=true, all font glyphs included,
	//embedAsCFF=true - FTE will be used
	[Embed(source="./font/enliven_design_element/Element.ttf", fontName="Element")]
	// Do not use this variable directly. 
	//It exists so that the compiler will link in the font.
	private static var Fontclass1:Class;
	//Embed multiple typefaces from otf files using the same font alias
	//advancedAntialiasing=true, Basic Latin unicode range included 
	//Notice that the same fontName alias used for each font-file embedded
	[Embed(source="./font/backpacker_bpreplay/BPreplay.otf", fontName="BPreplay", 
	fontStyle="normal", fontWeight="normal", embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass2:Class;
	[Embed(source="./font/backpacker_bpreplay/BPreplayBold.otf", fontName="BPreplay", 
	fontStyle="normal", fontWeight="bold", embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass3:Class;
	[Embed(source="./font/backpacker_bpreplay/BPreplayBoldItalics.otf", fontName="BPreplay", 
	fontStyle="italic", fontWeight="bold", embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass4:Class;
	[Embed(source="./font/backpacker_bpreplay/BPreplayItalics.otf", fontName="BPreplay", 
	fontStyle="italic", fontWeight="normal", embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass5:Class;
	  
	// Embed System font
	[Embed(systemFont="Tahoma", fontName="Tahoma", mimeType="application/x-font-truetype", 
	embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass7:Class;
	
	// Embed System font
	// advancedAntialiasing=false
	[Embed(systemFont="Tahoma", fontName="TahomaNoAdvancedAA", mimeType="application/x-font-truetype", 
	embedAsCFF="false", advancedAntiAliasing="false", unicodeRange="U+0020-007E")]
	private static var Fontclass8:Class;
	
	/* This embed from system font collection should work, but it did not for me 
	on Mac OS 10.6, flex 4.
	I expected to embed custom typeface "Futura Condensed Medium" from system font collection,
	however this code results in embedding "Futura" regular typeface instead.
	*/
	[Embed(systemFont="Futura", fontName="Futura", fontFamily="Futura Condensed Medium", 
	mimeType="application/x-font-truetype-collection",embedAsCFF="false",unicodeRange="U+0020-007E")]
	private static var Fontclass9:Class;
	
	/* When embedding system-font this property should include the font name and font face. 
	In this case the fontName property is generated automatically. 
	Notice that font name used for TextFormat.font property assignment is "Trebuchet MS", 
	not "Trebuchet MS Bold"
	*/
	[Embed(systemFont="Trebuchet MS", fontFamily="Trebuchet MS Bold", fontWeight="bold", 
	mimeType="application/x-font-truetype", embedAsCFF="false", unicodeRange="U+0020-007E")]
	private static var Fontclass10:Class;
	
	// embedding movieClip, created in Flash, containing bitmap font
	[Embed(source="bitmapFontTest.swf#bitmapFontContainer")]
	private static var MyFontHolder:Class;

	public function FontTest()
	{
		stage.scaleMode=StageScaleMode.NO_SCALE;
		stage.align=StageAlign.TOP_LEFT;
		makeBackground();
		var topBar:TopBar=new TopBar("Embedding fonts sample");
		addChild(topBar);
		
		var str:String = "Flash Text Engine Line, embedAsCFF=\"true\""; 
		var fd:FontDescription=new FontDescription("Element", "normal", "normal", 
			FontLookup.EMBEDDED_CFF); 
		var format:ElementFormat = new ElementFormat(fd, 30); 
		format.color=0x8F360E;
		var textElement:TextElement = new TextElement(str, format);
		var textBlock:TextBlock = new TextBlock();
		textBlock.content = textElement; 
		
		var textLine1:TextLine = textBlock.createTextLine(null, 750); 
		addChild(textLine1); 
		textLine1.x = 30; 
		textLine1.y = 70; 

		var str0:String="Multiple typafaces fontName=\"BPreplay\". Normal typeface";
		var str1:String="Multiple typafaces fontName=\"BPreplay\". Bold typeface";
		var str2:String="Multiple typafaces fontName=\"BPreplay\". Italic typeface";
		var str3:String="Multiple typafaces fontName=\"BPreplay\". Bold italic typeface";
		
		var textFormatBPreplay0:TextFormat=new TextFormat();
		textFormatBPreplay0.font="BPreplay";
		textFormatBPreplay0.size=22;
		var textFormatBPreplay1:TextFormat=new TextFormat();
		textFormatBPreplay1.font="BPreplay";
		textFormatBPreplay1.bold=true;
		textFormatBPreplay1.size=22;
		var textFormatBPreplay2:TextFormat=new TextFormat();
		textFormatBPreplay2.font="BPreplay";
		textFormatBPreplay2.italic=true;
		textFormatBPreplay2.size=22;
		var textFormatBPreplay3:TextFormat=new TextFormat();
		textFormatBPreplay3.font="BPreplay";
		textFormatBPreplay3.italic=true;
		textFormatBPreplay3.bold=true;
		textFormatBPreplay3.size=22;
		
		var textFieldBPreplay0:TextField=new TextField();
		textFieldBPreplay0.embedFonts=true;
		textFieldBPreplay0.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldBPreplay0.defaultTextFormat=textFormatBPreplay0;
		textFieldBPreplay0.selectable=false;
		textFieldBPreplay0.autoSize=TextFieldAutoSize.LEFT;
		textFieldBPreplay0.x=30;
		textFieldBPreplay0.y=90;
		
		textFieldBPreplay0.text=str0;
		
		var textFieldBPreplay1:TextField=new TextField();
		textFieldBPreplay1.embedFonts=true;
		textFieldBPreplay1.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldBPreplay1.defaultTextFormat=textFormatBPreplay1;
		textFieldBPreplay1.selectable=false;
		textFieldBPreplay1.autoSize=TextFieldAutoSize.LEFT;
		textFieldBPreplay1.x=30;
		textFieldBPreplay1.y=120;
		
		textFieldBPreplay1.text=str1;
		
		var textFieldBPreplay2:TextField=new TextField();
		textFieldBPreplay2.embedFonts=true;
		textFieldBPreplay2.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldBPreplay2.defaultTextFormat=textFormatBPreplay2;
		textFieldBPreplay2.selectable=false;
		textFieldBPreplay2.autoSize=TextFieldAutoSize.LEFT;
		textFieldBPreplay2.x=30;
		textFieldBPreplay2.y=150;
		
		textFieldBPreplay2.text=str2;
		
		var textFieldBPreplay3:TextField=new TextField();
		textFieldBPreplay3.embedFonts=true;
		textFieldBPreplay3.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldBPreplay3.defaultTextFormat=textFormatBPreplay3;
		textFieldBPreplay3.selectable=false;
		textFieldBPreplay3.autoSize=TextFieldAutoSize.LEFT;
		textFieldBPreplay3.x=30;
		textFieldBPreplay3.y=180;
		
		textFieldBPreplay3.text=str3;
		
		addChild(textFieldBPreplay0);
		addChild(textFieldBPreplay1);
		addChild(textFieldBPreplay2);
		addChild(textFieldBPreplay3);

		var str4:String="Tahoma system font embedded, 10px, advanced anti-alising";
		var str5:String="Tahoma system font embedded, 10px, NO advanced anti-alising";
		
		var textFormatTahoma0:TextFormat=new TextFormat();
		textFormatTahoma0.font="Tahoma";
		textFormatTahoma0.size=10;
		var textFormatTahoma1:TextFormat=new TextFormat();
		textFormatTahoma1.font="TahomaNoAdvancedAA";
		textFormatTahoma1.size=10;
		
		var textFieldTahoma0:TextField=new TextField();
		textFieldTahoma0.embedFonts=true;
		textFieldTahoma0.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldTahoma0.sharpness=250;
		textFieldTahoma0.defaultTextFormat=textFormatTahoma0;
		textFieldTahoma0.selectable=false;
		textFieldTahoma0.autoSize=TextFieldAutoSize.LEFT;
		textFieldTahoma0.x=30;
		textFieldTahoma0.y=220;
		
		textFieldTahoma0.text=str4;
			
		var textFieldTahoma1:TextField=new TextField();
		textFieldTahoma1.embedFonts=true;
		textFieldTahoma1.defaultTextFormat=textFormatTahoma1;
		textFieldTahoma1.selectable=false;
		textFieldTahoma1.autoSize=TextFieldAutoSize.LEFT;
		textFieldTahoma1.x=30;
		textFieldTahoma1.y=232;
		
		textFieldTahoma1.text=str5;
		
		addChild(textFieldTahoma0);
	    addChild(textFieldTahoma1);
		
		var str6:String="Expected to be Futura Condensed Medium typeface, " +
			"but resulted in Futura (regular)";
		
		var textFormatFutura:TextFormat=new TextFormat();
		textFormatFutura.font="Futura";
		textFormatFutura.size=18;
		
		var textFieldFutura:TextField=new TextField();
		textFieldFutura.embedFonts=true;
		textFieldFutura.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldFutura.defaultTextFormat=textFormatFutura;
		textFieldFutura.selectable=false;
		textFieldFutura.autoSize=TextFieldAutoSize.LEFT;
		textFieldFutura.x=30;
		textFieldFutura.y=255;
		
		textFieldFutura.text=str6;
		
		addChild(textFieldFutura);
		
		var str7:String="TextFormat.font=\"Trebuchet MS\" fontFamily=\"Trebuchet MS Bold\"";
		
		var textFormatTrebuchetMS:TextFormat=new TextFormat();
		textFormatTrebuchetMS.font="Trebuchet MS";
		textFormatTrebuchetMS.size=18;
		
		var textFieldTrebuchetMS:TextField=new TextField();
		textFieldTrebuchetMS.embedFonts=true;
		textFieldTrebuchetMS.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldTrebuchetMS.defaultTextFormat=textFormatTrebuchetMS;
		textFieldTrebuchetMS.selectable=false;
		textFieldTrebuchetMS.autoSize=TextFieldAutoSize.LEFT;
		textFieldTrebuchetMS.x=30;
		textFieldTrebuchetMS.y=280;
		
		textFieldTrebuchetMS.text=str7;
			
		addChild(textFieldTrebuchetMS);
		
		var textFormatPixel:TextFormat=new TextFormat();
		textFormatPixel.font="Arial Unicode MS_9pt_st";
		textFormatPixel.size=9;
		
		var textFieldPix:TextField=new TextField();
		textFieldPix.embedFonts=true;
		textFieldPix.antiAliasType=flash.text.AntiAliasType.NORMAL;
		textFieldPix.defaultTextFormat=textFormatPixel;
		textFieldPix.y=210; textFieldPix.x=350;
		textFieldPix.width=340;
		textFieldPix.wordWrap=true;
		textFieldPix.text="Bitmap font support is missing in Flex. This is WEIRD - small "+
			"bitmap fonts are much easear to read than anti-aliased fonts. This font was " +
			"created in Flash IDE, and embedded as an asset from swf file. Note the font" +
			"name in summary below";
		addChild(textFieldPix);
		
		var textFieldStats:TextField=new TextField();
		textFieldStats.embedFonts=true;
		textFieldStats.antiAliasType=flash.text.AntiAliasType.ADVANCED;
		textFieldStats.sharpness=400;
		textFieldStats.defaultTextFormat=textFormatTahoma0;
		textFieldStats.selectable=false;
		textFieldStats.autoSize=TextFieldAutoSize.LEFT;
		textFieldStats.multiline=true;
		textFieldStats.x=30;
		textFieldStats.y=310;
		textFieldStats.htmlText="<font color=\"#216633\" face=\"BPreplay\" size=\"12\">" +
			"<b>Embedded fonts summary:</b></font>\n"+getFontsListing();
		
		addChild(textFieldStats);
	}
	
	private function getFontsListing():String {
		var fontsListing:String="";
		var fontArray:Array = Font.enumerateFonts(false);
		fontArray.sortOn(['fontName']);
		for(var i:int = 0; i < fontArray.length; i++) {
			var thisFont:Font = fontArray[i];
			fontsListing+=thisFont.fontName+ " " + thisFont.fontStyle +"\n";
		}
		return fontsListing;
	}
	
	private function makeBackground():void {
		var rectCont:Sprite = new Sprite();
		addChild(rectCont);
		var matrix:Matrix = new Matrix();
		matrix.createGradientBox(1, stage.stageHeight, (Math.PI/180)*90, 0, 00);
		rectCont.graphics.beginGradientFill(GradientType.LINEAR,[0xB0C0C4,0xFFFFFF],
			[1,1],[0,255],matrix);
		rectCont.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
	}
}
}

download source code

9 responses


Do you want to comment?

Comments RSS and TrackBack Identifier URI ?

thanks you so much for your article. especially the part about font collection (.ttc).
I had a pb with American Typewriter Condensed (Bold and Normal) and solved it thanks to you and onlinefontconverter.com .

You saved my life !!! ;)

cheers :D

June 11, 2011 8:01 pm

Thanks for the examples. After trying about half an hour with adobe’s example and not getting the desired result (yep! The textbox didn’t show anything!!), I finally saw what was missing. PS. If someone is trying to use adobe’s example and the textbox, after embedding the desired font and inserting some texts, comes out empty, try embedding the same way the Breplay font was. Worked for me!

” [Embed(source=”./font/backpacker_bpreplay/BPreplay.otf”, fontName=”BPreplay”,
fontStyle=”normal”, fontWeight=”normal”, embedAsCFF=”false”, unicodeRange=”U+0020-007E”)]
private static var Fontclass2:Class;”

By the way, what does “embedAsCFF” means?

September 20, 2011 5:02 am

Very good stuff, thanks! I also love your Unicode Range Generator swf, it’s a real lifesaver!

September 26, 2011 10:55 am

Really nice info on what is a seemingly obscure topic. Not a lot of people seem to be able to figure it out.
The bitmaped fonts are particularly interesting. Thanks a lot!

September 29, 2011 2:40 am

Best up-to-date Flash & Font post I’ve read yet; it’s been helpful. Thank you taking the time to put this together!

October 6, 2011 12:41 pm

Wonderful article… I’ve had much trouble with font embedding and your solution to embed a SWF file with the bitmap font was the same conclusion I also came to.

You reason was what I found too – Flex does not render fonts as well as Flash IDE.

It seems embedding a SWF file with the fonts is the way to go.

Thanks for the in-depth report. This helps a lot.

December 3, 2011 3:20 am

Thanks a lot. Really good article!

March 1, 2012 10:40 am

embedAsCFF=”false” was exactly what I needed.

I recently moved a pure AS3 project from Flex Builder 3 project over to Flash Builder 4.5 and I couldn’t figure out why my fonts were no longer embedding. I suspect that the Flex 3 compiler assumed “false” so I hadn’t needed to declare it false. Now it must assume true, and that seems to screw up AS3’s basic TextField object.

May 27, 2012 2:01 am

ey there! you can also try Antialiaser (http://www.cycle-it.com/antialiaser/), an advanced tool amimed to embed fonts for flex3 and optimized mobile projects.
Regards.

June 5, 2012 1:35 pm

Comment now!
















Trackbacks