Posts Tagged chinese

Font embedding solution for AS3

The problem:

When embedding fonts in Flash or Flex the size of the swf becomes too big to be useful. If we embed simplified Chinese (13746 glyphs) the size of an empty swf with only a text-field is a whopping 3.9MB. Using flash with dynamic text together with embedded fonts is a real pain in the *ss. It seems there is no way to just use the glyphs you need and embed them at run-time.

Our solution:

When you load a swf in another swf the fonts embedded in the first swf become available in the second. So what if we compile an swf on the server with the letters we need and embed this swf as a “fontlibrary” in your main project. Because the flex SDK is now opensource (link) we can use flex without any extra cost to compile our fontlibrary in realtime on the server.

Example:

Here some code snippets to explain how we do it. It is not the full solution but just ask and i will complete the code some more
First we create an *.as file to compile on the server:

package {
	import flash.display.Sprite;
	import flash.text.*;

	public class ArialFontLib extends Sprite {  

	[Embed(source='ARIALUNI.TTF', fontName='_Arial', mimeType="application/x-font-truetype", unicodeRange = '@1@')]
	public static var _Arial:Class;  

		public function ArialFontLib()
		{
				super();
				 Font.registerFont(_Arial);
		}
	}
 }

We replace the @1@ tag with the unicode letters. Here an example of the [Embed] line after php reads the file and replaced the @1@ tag with the letters it got from the cms (drupal in this case)

[Embed(source='ARIALUNI.TTF', fontName='_Arial', mimeType="application/x-font-truetype", unicodeRange = 'U+6B61-U+6B61,U+8FCE-U+8FCE,U+9032-U+9032,U+5165-U+5165,U+5BCC-U+5BCC,U+901A-U+901A,U+8CC7-U+8CC7,U+7522-U+7522')]

Because the unicodeRange parameter needs a range we just repeat each code and thus create a 1 glyph range. As a font we use the Arial Unicode font.

Then we compile the as file with the following command in php:

exec("c:\flex\bin\mxmlc c:\fontdemo\ArialFontLib.as -managers flash.fonts.AFEFontManager -output fontlibrary.swf");

Note the -managers flash.fonts.AFEFontManager, this extra fontmanager is necessary to make it work and it is only available when you install the full flex 3 sdk (so not the light ones).

When this is done we just load the fontlibrary.swf we just created in our Flash project where we need the font.
The new font is available with the name “_Arial”.

Extras

Now we can create a service which generates a fontlibrary file when needed, we can use the function hasGlyphs to check if a textField can display the glyphs otherwise use the external fontlibrary. Here a little snippet to give you some idea how this should work.

public static function giveFormat(str:String, size:Number):TextFormat {
			var myFormat:TextFormat = new TextFormat();
			for each (var f:Font in Font.enumerateFonts()) {
				//trace(f.fontName);
				if (f.fontName == banner.externalFontName) {
					var t:Font = f;
				}
			}
			if (f.hasGlyphs(str)) {
				myFormat.font = banner.externalFontName;
			}else{
				myFormat.font = banner.defaultFontName;
			}
			myFormat.size = size;
			return myFormat;
		}

But more about this automated class solution later.

, ,

2 Comments