搜尋部落格文章

2013年11月26日 星期二

[轉] AS3專案嵌入字體

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 thefontName 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 thefontName 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 atAdobe Flash Builder 4/sdks/4.0.0/frameworks/). The file contains tag, for setting up ranges. The flash-unicode-table.xmlfile(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 onadobe. 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.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 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:
?
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:


form: http://inspiritgames.com/blog/2010/09/embed-fonts-into-pure-as3-project/
source code download