縦書きの文字列を表示する必要が出てきたので、TextLayoutFormat (TLF)について勉強してみます。
まだ制作用のPCにFlash CS5が入っていない(というか、CS4も入っていない。使ってるのはCS3です)ので、このままだとTLFが使えない。CS5はそのうち導入する予定だけど、取り急ぎFlashDevelop + Flex4SDKの組み合わせでなんとかならんか試してみます。
サンプルの入手
SourceForgeにAdobeがTLFのページを作っているので、そこからサンプルファイルをゲット。
Text Layout Framework / Dashboard
上記のページの上の方にある「Download examples.」というリンクをクリックして、サンプルファイル一式の詰まったzipファイルをダウンロード。解凍して出てくるのは「actionscript」「flex」という2つのフォルダ。「flex」の方はmxmlでの開発用なので、今回使うのは「actionscript」フォルダの方かな。
FlashDevelopで開く
FlashDevelopを立ち上げ、上部メニューから「プロジェクト>プロジェクトをインポート」を選択。ダウンロードした「actionscript」フォルダの中にある「TextLayout¥.actionScriptProperties」を選択。
すると無事にプロジェクトが開いた!やった~。
早速Ctrl+Enterでプロジェクトをテスト。あれ?エラーが出る??
C:¥Program Files¥FlashDevelop¥Tools¥flexsdk¥frameworks¥flex-config.xml(53): Error: unable to open ‘libs/player/9.0/playerglobal.swc’
む。FlashPlayerの書き出しバージョンの問題か?というわけで、FlashDevelopのプロジェクト設定の「書き出し」タブでプレーヤーのバージョンをFlashPlayer10に変更。
改めてプロジェクトをテスト。すると・・・おお、ビルド成功!!
swcの読み込み
さてさていろいろいじってみるか。・・・と思ったものの、あれ?TLF関係のクラスのコード補完が出ない?調べてみると、どうやらTLF関連のswcファイルを設定しないとコード補完などが使えない様子。というわけで、swcファイルを読み込みます。
FlashDevelopのインストール時にFlexSDKも一緒にインストールした場合、TLF関連のswcであるtextLayout.swcは、以下の場所にあります。
C:¥Program Files¥FlashDevelop¥Tools¥flexsdk¥frameworks¥libs¥textLayout.swc
というわけで、プロジェクト設定の「コンパイラー設定」タブを開きます。
で、「Advanced | 高度な設定」の中にあるSWC Librariesの行をクリックし、右端に表示されるボタンをクリックして出てくる「文字列コレクション エディタ」のウィンドウに上記のパスをペースト。
すると、TLF関係のクラスに色がついて、コード補完も使えるようになりました!
ちなみにこのswcファイル、先程のSourceForgeのサイトからも落とせる模様。
File Manager – SourceForge Downloads
上記のDownload textLayout_build.zipと書いてある箇所をクリックすると、swcやらasやらドキュメントやらまとめて入ってるzipファイルがゲットできます。Looking for the latest version?と書いてあるから、ひょっとするとSDK付属のものとバージョンが違うのかな?
縦書きの表示
次に縦書き表示に挑戦。参考にしたのは下記のページ
feb19.jp blog – Flash CS5 を予習 ~Text Layout Framework (TLF) 編~
先程のAdobeのサンプルに、feb19さんのコードを参考にしてコードを追加してみました。とりあえず縦書き表示させるために、TextFlow.directionプロパティとTextFlow.blockProgressionプロパティを設定。
////////////////////////////////////////////////////////////////////////////////<br /> //<br /> // ADOBE SYSTEMS INCORPORATED<br /> // Copyright 2008-2009 Adobe Systems Incorporated<br /> // All Rights Reserved.<br /> //<br /> // NOTICE: Adobe permits you to use, modify, and distribute this file<br /> // in accordance with the terms of the license agreement accompanying it.<br /> //<br /> //////////////////////////////////////////////////////////////////////////////////</p> <p>package {<br /> import flash.display.Sprite;<br /> import flash.text.engine.TextBaseline;<br /> import flashx.textLayout.formats.BlockProgression;</p> <p> import flashx.textLayout.compose.StandardFlowComposer;<br /> import flashx.textLayout.container.ContainerController;<br /> import flashx.textLayout.elements.ParagraphElement;<br /> import flashx.textLayout.elements.SpanElement;<br /> import flashx.textLayout.elements.TextFlow;<br /> import flashx.textLayout.formats.Direction;</p> <p> /** Simplest possible "Hello, World" text example */<br /> public class HelloWorld extends Sprite<br /> {<br /> public function HelloWorld()<br /> {<br /> var textFlow:TextFlow = new TextFlow();<br /> textFlow.locale = "ja";<br /> textFlow.direction = Direction.LTR;<br /> textFlow.blockProgression = BlockProgression.RL;</p> <p> var p:ParagraphElement = new ParagraphElement();<br /> textFlow.addChild(p);</p> <p> var span:SpanElement = new SpanElement();<br /> span.text = "当帝の外戚の大臣一派が極端な圧迫をして源氏に不愉快な目を見せることが多くなって行く。つとめて冷静にはしていても、このままで置けば今以上な禍いが起こって来るかもしれぬと源氏は思うようになった。";<br /> span.fontSize = 24;<br /> p.addChild(span);</p> <p> textFlow.flowComposer.addController(new ContainerController(this, this.stage.stageWidth, this.stage.stageHeight));<br /> textFlow.flowComposer.updateAllControllers();<br /> }<br /> }<br /> }
feb19さんのコードと比べると、一部のクラス名が変わっている模様(DisplayObjectContainerController → ContainerControllerとか)
んでテストしてみたのがこちら。
おお~。縦書きになってる!・・・けど、文末の句読点の位置おかしくね?ということで、その後feb19さんのページを参考にさらにコードをいくつか追加みたんですが、まだ解決せず。今後の課題ですな。とりあえず、縦書きが表示できたので今日のところは良しとします。
追記:解決しました。textFlow.directionの値がDirection.RTLだったのをDirection.LTRにしたら直りました。
ちょっと戸惑ったのはTextFlowインスタンス。これ、DisplayObjectじゃないんですね。じゃあどうやってステージ(など)に表示させてるんだろう?と思ったら、feb19さんの記事に書いてありました。
テキストを入れていったら、TextFlow.flowComposer.addController() で DisplayObejctContainer のツリーに参加させて、TextFlow.flowComposer.updateAllContainers() で内容を更新します。
なるほどー。TextFieldとは全く扱い方が違うんですね。これは早く慣れねば。