[AS3]フォントの外部swf化と、その動的な読み込み

| コメント(2)
CS3版のフォントを外部からロードする方法はKAYACさんのブログで紹介されおりました。

しかしながらprogressionでいざ!と思ったときにハマってしまった。

また同じことを繰り返しそうなのでメモ。

と、いうか実際動いたというだけで完全解決していないが。。。


やりたいこととしてはprogressionのインデックスシーンでフォントを読み込んで、

色々なところで使いまわしたいという単純な話。

一応最初から順を追って書いておく。

流れとしては

1 - フォントswfを作成する

2 -フォントswfのロード。

3 - フォントを登録

4 - テキストフォーマットでフォントを指定しテキストフィールドに使用する。

という感じになる。


■1 フォントswfを作成する

Flash CS3からならフォントの外部出力自体は至極簡単。

flafont01.gif

ライブラリーに新しいフォントを作成し、プロパティからフォント名、フォントを設定する。

さらにリンゲージを設定して、パブリッシュ!

リンゲージ名は後でロード側で呼び出す際に使うので忘れずに。

というか、忘れてて一度あわてた。

ここではフォント名をFontSampleとしてFontSample.swfを吐き出したとする。


■2 フォントをロードする

public function init():void {
	var req :URLRequest = new URLRequest("FontSample.swf");
	var loader:Loader = new Loader();
	var context :LoaderContext = new LoaderContext();
	context.applicationDomain = ApplicationDomain.currentDomain;
	loader.contentLoaderInfo.addEventListener( Event.COMPLETE, onLoadComplete );
	loader.load( req, context );
}
		
public	function onLoadComplete( e:Event ) {
	e.target.removeEventListener( Event.COMPLETE, onLoadComplete );
	
	var FontLibrary:Class = ApplicationDomain.currentDomain.getDefinition("FontSample") as Class;

	Font.registerFont( FontLibrary);	
	var allFonts:Array = Font.enumerateFonts(false);
	trace(allFonts);
}

さてこの最下部のtrace出力は以下のようになる。

[object FontSample]


自分の中でLoaderContextおよびApplicationDomainまわりがよくわからない。

ということでとりあえずヘルプを読んだが、いまいち固くて分かりづらい。

が、そもそもLoaderクラスのloadメソッドの第二引数はcontext:LoaderContextとなっている。

LoaderContextとは何かというと

  • オブジェクトのロード時に Flash Player がポリシーファイルの存在を確認するかどうか
  • ロードされるオブジェクトの ApplicationDomain
  • ロードされるオブジェクトの SecurityDomain
を設定できるものだとさ。(原文引用)

で、セキュリティドメインももちろん大事なんですが、今回はアプリケーションドメインの方が

問題になっているわけです。



■2-2 ApplicationDomainってなんすか。

ApplicationDomainというのは実行コードの管理単位だそうな。@ITに詳細があった。

Flashにおいては、クラスとその中のコードのまとまりってことですか。

ヘルプにあった図は納得いった。

そのまとまりは表示リストのように階層構造をなしていて

親ファイルが子ファイル内のクラスを参照したり、その逆だったり、ということができると。


通常はメインswfでは

システムドメイン ---メインアプリケーションドメインとなっているのかな。

そこに新たに子swfをロードする際には3つの階層構造がある。

(1) - システムドメインに子ドメインを新たに作成
 -----------------------------------------------------------------
 システムドメイン
      |
      |---- メインドメイン
      |
      |---- 新ドメイン←子swfファイルのクラス
 -----------------------------------------------------------------
同名クラスで挙動が違っても競合しない。

request.url = "application2.swf";
request.applicationDomain = new ApplicationDomain();


(2) - メインドメインにロードしたswf内のクラスを定義する
-----------------------------------------------------------------
 システムドメイン
      |
      |---- メインドメイン←子swfファイルのクラス-----------------------------------------------------------------          
子swfファイル内のクラスが新たに現在のドメインに追加される。
親子はクラスを共有できる。

request.url = "module1.swf";
request.applicationDomain = ApplicationDomain.currentDomain;


(3) - メインドメインの子ドメインを作成
-----------------------------------------------------------------
  システムドメイン
      |
      |---- メインドメイン
            |----- 子ドメイン + 子swfファイルのクラス
-----------------------------------------------------------------
現在のドメインに新たに子ドメインが作成される。
子から親は参照できるが親から子は参照できない。

request.url = "module3.swf";
request.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);

先のLoadContext内のアプリケーションドメインはこういった設定を行っていたということでした。

なるほど。それでFace'sサンのスライドではcurrentDomainが楽とおっしゃっていたのですね。


で、クラスの取り出しなんだが、currentDomainでは前述の通り

ApplicationDomain.currentDomain.getDefinision(クラス名) as Class


でいけるですが、ヘルプ内よりもうひとつ。ドメインを分けた場合にも使えるやり方を(たぶん)。

loader.contentLoaderInfo.applicationDomain.getDefinition(className)  as  Class;


ヘルプ以外でのアプリケーションドメインの参考は以下のブログ様です。

http://blogs.adobe.com/akamijo/archives/2006/03/applicationdoma.html

http://www.at-sonic.com/blog/archives/2008/02/swfswfnew.php

http://blog.eternitydesign.net/archives/2008/07/swfswf.html


長くなってしまったので、次のエントリーで続きを書くことにします。

コメント(2)

あんま先々進まないでー、不安になるから。笑
flash最近触ってないから、元々あんま理解してないAS2すら忘れてしまったよ。

あと、英語ができるのはやっぱ羨ましいなあと思う。
(怪しいリンク踏むこともなさそうやしw)

来年こそはflashと英語を頑張ろう!気が向いたらおせーてw
では、また。