2009年9月アーカイブ

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


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

食品の安全性は一時期メディアでずいぶん騒がれていた話題だ。

特に中国の餃子やらなんやらで盛りあがっていたのは記憶に新しい。

気になりつつも、食にまつわることはほとんど無知な私。

だが、今日気になる文言を目にした。


それが「放射線照射食品」。

臭化メチルなどに代わって、食品の食中毒予防、殺菌、殺虫のために

放射線を照射する技術だそうで。

日本では1970年代からじゃがいもの発芽防止のために使用が許可されているとか。

世界各国では安全性、有用性が認められ、特に香辛料などで使用される例が多く、

現在、日本でもじゃがいも以外の照射を認めさせる動きがあるとのこと。



ぶっちゃけ安全性に関しては、素人の私なんぞにはまったくわからないけど、

なんでそこまでして発芽や中毒予防や殺菌が必要なのかは疑問だ。。。

農薬より安全(そう)で大量生産と遠方への移動が可能な技術が必要だってことなのか。

食料輸出国の論理なような気もするけどなぁ。

U○Aなら日本人は歴史から感情を引きずりすぎだとか批判してきそう。

地産地消なんて流行り言葉の裏じゃ、こんなことがまだまだ発展していくのだろうか。


消費者が選べばいい話かと言えば、ワックスべったべたに塗ってある林檎やみかんと違って

こんなもの目に見えないから、選びようがないって。

って批判的に書いたけど、わからないうちは静かに動向を見てみることにしようかな。

とりあえず今度三菱研究所の
食品への放射線照射についての科学的知見のとりまとめ業務報告書
てのを読んでみようかしらん。

web以外のメモは初。

BulkLoader

make loading and managing complex loading requirements easier and faster

だそうです。


いろんな形式のファイルを一括でロードしてくれる便利なライブラリーを発見。自分用メモメモ。
(以下googlecodeの引用に手を加えています。問題があったら教えてください。)


使い方は以下の流れで
1 - インポート
2 - BulkLoaderのインスタンスを作成
3 - ロードするURLをセットする
4 - リスナーをセットする。すべてのアイテムに対してもできるし、個々に対してもできる。
5 - ロードをスタート
6 - ロードしたコンテンツを取得


1 - インポート

import br.com.stimuli.loading.BulkLoader;  
import br.com.stimuli.loading.BulkProgressEvent;


2 - BulkLoaderのインスタンスを作成

// 引数にインスタンスの名前を付けるみたい。後でコンテンツを取得する際に使用できる。
var loader:BulkLoader = new BulkLoader("main-site");


3 - ロードするURLをセットする

// 簡単な場合
loader.add("logo.png");
// idを付与しておけば後で取得する際にURLは必要ない
loader.add("background.jpg", {id:"bg"});
// URLがファイルタイプを示していない場合はバルクローダーにタイプを教えてあげる。
loader.add("/some-web-services?size=Large", {type:"image"});
// 優先してロードするようにしたい場合はプライオリティ値を与えてあげる。
loader.add("/data/config.xml", {priority:20});
// 最大試行回数 デフォルトは三回
loader.add("/unreliable-web-services.xml", {maxTries:6});
// URLRequestオブジェクトも使用可能。これはPOSTリクエストでロードする。(これはあんまり意味がわからない。。。
var postRequest : URLRequest = new URLRequest("/save-prefs.php");
postRequest.method = "POST";
var postData : URLVariables = new URLVariables(myPostDataObject );
postRequest.data = postData;
loader.add(postRequest, {"id":"settings"});
// 全てのオプションを組み合わせることも可能
loader.add("the-sound-webservices?name=maintrack", {"id":"soundtrack", type:"sound", maxTries:1, priority:100});


4 - リスナーをセットする

// 全てのアイテムがロード完了
loader.addEventListener(BulkLoader.COMPLETE, onAllLoaded);
// 全てのどんなアイテムでも読み込み状態を取得
// BulkProgressイベントはProgressEventのサブクラス
loader.addEventListener(BulkLoader.PROGRESS, onAllProgress);
// ロード中のファイルのどれかがミスると発動
loader.addEventListener(BulkLoader.ERROR, onAllError);                                      
            
// bgと名前を付けたアイテムがロード完了すると発動(ほかにまだ残ってても)
loader.get("bg").addEventListener(Event.COMPLETE,onBackgroundLoaded)
// config.xmlがミスると発動
loader.get("data/config.xml").addEventListener(BulkLoader.ERROR, onXMLFailed)


5 - ロードをスタート

loader.start();


6 - ロードしたコンテンツを取得

var theBgBitmap : Bitmap = loader.getContent("bg") as Bitmap;
// インスタンスを参照しなくても、付与した名前からも取得できる
var theBgBitmap : Bitmap = BulkLoader.getLoader("main-site").getContent("bg") as Bitmap;
// 省略形
var theBgBitmap : Bitmap = loader.getBitmap("bg");
// ビットマップデータを直接取得
var theBgBitmap : Bitmap = loader.getBitmapData("bg");


てな感じ。


参考にさせていただいた記事は以下
ONE OP IXEL | [AS3.0]複数の外部画像をまとめてローディング表示
ありがとうございました。


ちなみにONE OP IXELさんで書かれていたプログレスの取得percentLoadedだと
なぜか60%以上からしか値が変化しなかったので
私はweightPercentを使ってみました。

private function onProgress(e:BulkProgressEvent) : void{  
         //読み込み率を整数に
	 var tmp_num:int=int(e.weightPercent *100); 
	 //表示テキスト
	 prog_txt.text="PHOTOES..."+ tmp_num +"%";
	}  


こんな感じで。