« ApplicationDomain | Home | 自らの内部、よって立つ根幹への本質的な批判のまなざし »

Feb 062009

AS3での埋め込みフォントの共有について:其の壱(未解決)

以前apeirophobia: 特定の文字だけを埋め込んだフォントのランタイム共有方法(AS 2.0)というエントリーを書いたけど、今度はAS3版。既出のリソースとしては
FACEs: as3:フォントのダイナミックなローディング
CS3版 フォントのダイナミックなローディング|_level0.KAYAC
あたりが有名なところ。


で、このやり方で読み込む親SWFの中に同じフォントを用いた静止テキストを配置すると、フォントが表示されなくなるという問題がある。これはPlayer8以前に見られたフォントのconflictと同じような状態(詳細はapeirophobia: 特定の文字だけを埋め込んだフォントのランタイム共有方法(AS 2.0))。恐らくフォントクラスが親SWFで先に設定されてしまうことで、外部SWFのフォントクラスが適応されないというのが理由だと思う。(そう考えるとPlayer8の原因とは違うのかもしれないけど)
簡単に検証したい人はCS3版 フォントのダイナミックなローディング|_level0.KAYACのサンプルをDLして、loader.flaのステージ上にAXIS Std Hで静的テキストを配置すると再現できます。


AS3から外部SWFのクラスアクセスはApplicationDomainの設定も絡んできて、ちょっと原因の切り分けがややこしくなっているので、検証してみました。

なんか良く分からない部分もあるのですが、とりあえず忘れないようにダラダラ書いておきます。

まず、Faces、Kayacのやっているやり方で、親SWFに同じフォントで静止テキストを配置すると、dynamic fieldへのembed fontはすべてNG、レンダリングされなくなります。

ということで、外部SWFの方でフォントクラスの処理をしてみる。
手法としては
1)Fontクラスを戻す。フォントクラスの直接定義。これは同じSWFの中の埋め込みフォントのインスタンス化と一緒。フォントのリンケージ名を「FontEn」とした場合

public function get fontClass():Font
{
	return new FontEn();
}

2)Fontクラスを戻す。(※Font.registerFontはあえてはずしています)
埋め込み時

var font_en:Class = ApplicationDomain.currentDomain.getDefinition( "FontEn" ) as Class;
Font.registerFont(font_en);
registerClassAlias("fontClassEn", font_en);

取得時

public function get fontClass2():Font
{
	var tmpFontClass:Class = getClassByAlias("fontClassEn");
	return new tmpFontClass();
}

3)TextFormatを戻す

public function get textformat():TextFormat
{
	var tmpFont:Font = fontClass;
	return new TextFormat( tmpFont.fontName, 24 );
}

4)TextFormatを設定したtextFieldを戻す

public function get textfield():TextField
{
	var txt:TextField = new TextField();
	txt.autoSize = TextFieldAutoSize.LEFT;
	txt.type = TextFieldType.INPUT;
	var ffffont:Font = fontClass;
	txt.defaultTextFormat = new TextFormat( ffffont.fontName, 24 );
	txt.embedFonts = true;
	return txt;
}

5)引数で渡されたTextFieldにTextFieldを適応する

public function setFormat(txt:TextField):void
{
	txt.autoSize = TextFieldAutoSize.LEFT;
	var ffffont:Font = fontClass;
	txt.defaultTextFormat = new TextFormat( ffffont.fontName, 24 );
	txt.embedFonts = true;
}

で、それぞれ外部のApplicationDomainを
a)new ApplicationDomain();
b)ApplicationDomain.currentDomain;
c)new ApplicationDomain(ApplicationDomain.currentDomain);
でやってみる。

で、結果はApplicationDomainの設定に関わらず、4)以外はNGでした。
ApplicationDomainはあまり関係ないようです。(まぁキチンと参照すれば良いだけの話ですが)


多分静的テキストフィールドで使用されているフォントは自動的にFontクラスに登録されているので、そこらへんでバッティングが起きているのだと思います。問題はTextFormatへのフォント指定がClass名ではなく、Font.fontnameというString形式になっていることで、その辺を何とかしてくれたら素敵なのになぁ・・と思います。(直接埋め込んでいる方のFlaではフォント選択に、リンケージ名のフォントが表示され、それで設定が可能ですが、これはまた別のフローで定義されているのかもしれません。)

ということで参考までに検証に使ったソース一式アップしました。(※要Progression
こちらからhttp://www.img8.com/src/test_ex_font.zip

なんか良い解決法があったら教えてください(誰

引き続き調べてみます。

2 Comments

このシリーズ、すごく勉強になるのですが、やはり普通に考えるとオーサリングソフト側でスマートに実装すべきですよね……。検証作業、本当にお疲れさまです。(;´д`)/

どうですかねえ?
各SWFファイルをフレームワーク的に考えると、本体の更新に引きずられてフォントデータも再度読み込みなおすというのはユーザへの読み込み負荷って部分でどうかな?と思います。
(更新が無いコンテンツであればよいですが)

まぁコンテンツの内容次第でしょうね。(でも基本的に常にフォントは外部SWFにしてキャッシュを出来るだけ利用するようにします)

Leave a comment

Search and Archives