gembin

OSGi, Eclipse Equinox, ECF, Virgo, Gemini, Apache Felix, Karaf, Aires, Camel, Eclipse RCP

HBase, Hadoop, ZooKeeper, Cassandra

Flex4, AS3, Swiz framework, GraniteDS, BlazeDS etc.

There is nothing that software can't fix. Unfortunately, there is also nothing that software can't completely fuck up. That gap is called talent.

About Me

 

Embedding fonts into ActionScript 3 project

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):

1
[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:

1
2
[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:

1
2
[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:

NameDescriptionAcceptable valuesDefault value
systemFontExact name of the font installed on your system. Use either this or source parameter.String name of the font, e.g. "Arial"-
sourceRelative or absolute path to the font file.path string, e.g."./font/MyriadPro-Regular.otf"-
fontNameString 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-
fontFamilyProperty 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 alsoEmbedding multiple typafaces from container file formatsbelow.
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.-
unicodeRangeUnicode 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 useUnicode 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 intoflex-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 inflex-config.xmlfile
advancedAntiAliasingProperty determines whether to include advanced anti-aliasing information when embedding the font. Advanced antialiasinghelps 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 falsetrue
embedAsCFFNew 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 falsetrue
fontWeightProperty sets the type-face value of the font. Property should be used only when required for embeddable font.normal, bold, heavynormal
fontStyleProperty sets the type-face value of the font. Property should be used only when required for embeddable font.normal, italic, obliquenormal
mimeTypeThis 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 Identifierfield value;
  5. After the symbol created, publish document.

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

1
2
3
// 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:

Source code, concluding written above:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
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