AS3: Fonts einbetten und auswählen

Wahrscheinlich gibt es eine Reihe von Methoden, um Fonts zur Laufzeit zu laden. Ich habe heute eine relativ einfache Methode verwendet, die bisher sehr gut funktioniert und die ich im Folgenden kurz erläutern möchte.

1. Zunächst erstellt man einen neuen AS3-Flashfilm und bindet beliebig viele Fonts, in die Bibliothek eines Flashfilms, z.B. „fonts.swf“ ein. Jeder Font wird für AS exportiert und ein entsprechender Klassenbezeichner zugewiesen. Danach wird die SWF kompiliert.
2. In einer Klasse lädt man die Fonts, wie folgt:

private function loadFonts():void{
	var font = new LoadFont("assets/fonts/fonts.swf",["BillyBold","BetterGirl"]);
 	 font.addEventListener(LoadFont.COMPLETE, successLoadFont);
 	 font.addEventListener(LoadFont.ERROR, failLoadFont);
}
private function failLoadFont(e:Event){
 	  trace("Error: Font-Loading");
}
 private function successLoadFont(e:Event){
 	 embeddedFonts = Font.enumerateFonts(false);
 	 aktFont = embeddedFonts[0].fontName;
	 initUI();
 }

„BillyBold“ und „BetterGirl“ entsprechen den Klassenbezeichnern der fonts.swf. „aktFont“ ist eine private-Eigenschaft (String) der Klasse. Am Anfang setze ich den Wert der Eigenschaft auf das erste Feld des Arrays „embeddedFonts“.

3. Die LoadFont-Klasse sieht wie folgt aus:

package com.medianetic.tools {
	import flash.events.EventDispatcher;
	/**
	 * ...
	 * @author NW
	 */
	import flash.display.*;
 	import flash.events.*;
 	import flash.text.*;
 	import flash.errors.*;
 	import flash.system.*;
 	import flash.net.*;
 	public class LoadFont extends EventDispatcher {
 	 	public static const COMPLETE:String = "complete";
 	 	public static const ERROR:String = "error loading font";
 	 	private var loader:Loader = new Loader();
 	 	private var _fontsDomain:ApplicationDomain;
 	 	private var _fontName:Array;
 	 	public function LoadFont(url:String,fontName:Array):void {
 	 	 	_fontName = fontName;
 	 	 	trace("loading");
 	 	 	loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, font_ioErrorHandler);
 	 	 	loader.contentLoaderInfo.addEventListener(Event.COMPLETE,finished);
 	 	 	loadAsset(url);
 	 	}
 	 	private function loadAsset(url:String):void {
 	 	 	var request:URLRequest = new URLRequest(url);
 	 	 	loader.load(request);
 	 	 }
 	 	function finished(evt:Event):void {
 	 	 	_fontsDomain = loader.contentLoaderInfo.applicationDomain;
 	 	 	registerFonts(_fontName);
 	 	 	dispatchEvent(new Event(LoadFont.COMPLETE));
 	 	}
 	 	function font_ioErrorHandler(evt:Event):void {
 	 	 	dispatchEvent(new Event(LoadFont.ERROR));
 	 	 }
 	 	public function registerFonts(fontList:Array):void {
 	 	 	for (var i:uint = 0; i < fontList.length; i++) {
 	 	 	 	Font.registerFont(getFontClass(fontList[i]));
 	 	 	}
 	 	}
 	 	public function getFontClass(id:String):Class {
 	 	 	return _fontsDomain.getDefinition(id) as Class;
 	 	 }
 	 	public function getFont(id:String):Font {
 	 	 	var fontClass:Class = getFontClass(id);
 	 	 	return new fontClass as Font;
 	 	}
 	}
}

Achtung: "embeddedFonts = Font.enumerateFonts(false);" enthält nicht nur alle geladenen Fonts, sondern auch alle Fonts, die als eingebette Fonts auf dem System verfügbar sind. Wenn man Fonts selektieren will und nutzen möchte, muss man also noch eine Abfrage, wie z.B. diese hier machen (Code-Snippet!):

private function changeFont(e:Event=null):void {
	var index:uint = fontList_cb.selectedIndex;
	var targetFontName:String = fontList_cb.getItemAt(index).data;
	var resultFont:String;
	for (var i:uint = 0; i < embeddedFonts.length; i++) {
		if (targetFontName == embeddedFonts[i].fontName) {
			resultFont = embeddedFonts[i].fontName;
		}
	}
	aktFont = resultFont;
	formatText(inputText, inputText.text, 0x000000, "left", false, 240);
	trace("Activating Font: " + resultFont);
}

Achtung ;) Man muss darauf achten, dass der Schriftname (nicht der Klassenbezeichner, nicht der Schriftname in Flash) mit "fontName" übereinstimmt. Ich habe den in einer XML manuell selbst eingetragen und der steht bei mir im data-Feld einer ComboBox: fontList_cb.getItemAt(index).data; Tatsächlich hat bei diesen Fonts der Font BillyBold den Schriftnamen "BillyBold" und BetterGirl den Schriftnamen "Better Girl" (mit Leerzeichen).

Achtung ;) Das ist kein Copy&Paste-Code.

*happy coding*

Schreibe einen Kommentar