動作確認環境
- Windows7 64bit
- FlexSDK 4.6, FlashPlayer 11.7
- FlashDevelop 4.4.0
Flashで、ActionScript3.0を使用してテキストを縦書きする方法には、
- TLF (TextLayoutFramework)を使う方法
- FlashTextEngineを使う方法
があるようだ。どちらもFlashPlayer10(FlashProCS4)以降で使える。
TLF(TextLayoutFramework)とFlashTextEngine
TLFは、FlashProで扱うなら fl.text.TLFTextField クラスを使ってわりと簡単に扱えるようだが、FlexSDKで扱うならTLFTextFieldクラスを使えず面倒な作業が必要になるようだ。
Flash Professional CS5 では、TLF 機能をカプセル化する fl.text.TLFTextField という新しいクラスが提供されています。この TLFTextField クラスは、TLF の高度なテキスト表示機能を使用するテキストフィールドを ActionScriptで作成するために使用します。TextField クラスを使用してテキストフィールドを作成する場合と同じ方法で、TLFTextField オブジェクトを作成します。
Flexで作業している場合は、TLF クラスを使用します。詳しくは、Text Layout Framework の使用を参照してください。
引用元: Adobe Flash Platform * Text Layout Framework の使用 http://help.adobe.com/ja_JP/as3/dev/WSb2ba3b1aad8a27b0-1b8898a412218ad3df9-8000.html
これまでのTextFieldインスタンス([クラシックテキスト])をタイムラインに動的に配置して、その文字を設定する‥‥
これと同じテキストを[TLFテキスト]でつくるには、クラスをTextFieldからTLFTextFieldに書替えるだけです。ただし、TLFTextFieldクラスを使うには、import宣言する必要があることに注意してください。
もちろん、TextFieldクラスにはできなかった機能がTLFTextFieldクラスに加わっています。たとえば、テキストを動的に縦書きにすることです。
引用元: ActionScript 3.0から見るFlash Professional CS5 http://www.adobe.com/jp/devnet/flash/articles/actionscript30_CS5.html
一方FlashTextEngineなら、FlexSDKでも簡単に導入・使用できるらしい。
- Adobe Edge: 2010年3月 第7回 TextBlockクラスで多彩な文字表現 http://www.adobe.com/jp/newsletters/edge/march2010/articles/article3/
この記事を参考に、学んでみる。
FlashTextEngine 横書き
package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.text.engine.ElementFormat; import flash.text.engine.FontDescription; import flash.text.engine.TextBlock; import flash.text.engine.TextElement; import flash.text.engine.TextLine; /** * ... * @author itouhiro */ [SWF(width="480",height="360",backgroundColor="0xfcfcfc",frameRate="30")] public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point var str:String = "The quick brown fox jumps over the lazy dog\nいろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす"; var font_regular:FontDescription = new FontDescription('Meiryo', 'normal'); var font_bold:FontDescription = new FontDescription('Meiryo', 'bold'); var fmt:ElementFormat = new ElementFormat(); fmt.locale = 'ja'; fmt.fontDescription = font_regular; fmt.fontSize = 24; fmt.color = 0x333333; var elem:TextElement = new TextElement(str, fmt); var block:TextBlock = new TextBlock(); block.content = elem; var width:int = 320; //px var linespace:int = 5; //px var offset:Point = new Point(0, 0); //textblockの左上端 var next:Point = new Point(0, 0); var line:TextLine = block.createTextLine(null, width); while (line !== null) { line.x = next.x + offset.x; line.y = next.y + offset.y; next.y += line.ascent + line.descent + linespace; //次の行の位置を指定する 横書きのとき addChild(line); //実行しないと画面を更新しない line = block.createTextLine(line, width); } } } }
こんなソースをコンパイルすると、以下のような実行画面になる。
最初の行が欠けてる。
原因はTextBlockの左上端 (0,0) はフォントのベースラインの位置になるからのようだ。
だから
var offset:Point = new Point(0, 24);
とかにすれば解決。
FlashTextEngine 縦書き
縦書きはソースを以下のように変更する。
--- R:/20130426flashtextengine/src/Main.as Fri Apr 26 08:39:33 2013 +++ R:/20130426flashtextengine2/src/Main.as Fri Apr 26 08:49:52 2013 @@ -8,6 +8,7 @@ import flash.text.engine.TextBlock; import flash.text.engine.TextElement; import flash.text.engine.TextLine; + import flash.text.engine.TextRotation; /** * ... @@ -41,17 +42,19 @@ var elem:TextElement = new TextElement(str, fmt); var block:TextBlock = new TextBlock(); block.content = elem; + block.lineRotation = TextRotation.ROTATE_90; //縦書き var width:int = 320; //px var linespace:int = 5; //px - var offset:Point = new Point(0, 24); //textblockの左上端 + var offset:Point = new Point(480 - 24, 0); //textblockの左上端 var next:Point = new Point(0, 0); var line:TextLine = block.createTextLine(null, width); while (line !== null) { line.x = next.x + offset.x; line.y = next.y + offset.y; - next.y += line.ascent + line.descent + linespace; //次の行の位置を指定する 横書きのとき + next.x -= line.ascent + line.descent + linespace; //次の行の位置を指定する 縦書きのとき addChild(line); //実行しないと画面を更新しない line = block.createTextLine(line, width);
半角英数字と全角文字の切り替わる行で、TextLine.descentが無視されてるような‥‥。
でも縦書きのときは普通、半角英数字は使わないので、いいか。
var font_regular:FontDescription = new FontDescription('GL-AntiquePlus', 'normal'); var fmt:ElementFormat = new ElementFormat(); fmt.locale = 'ja'; fmt.fontDescription = font_regular; fmt.fontSize = 24; fmt.color = 0x333333;
の行は、まとめて
var fmt:ElementFormat = new ElementFormat(new FontDescription('GL-AntiquePlus', 'bold'), 24, 0x333333); fmt.locale = 'ja';
と書ける。
var block:TextBlock = new TextBlock(); block.content = elem; block.lineRotation = TextRotation.ROTATE_90; //縦書き
の行は、まとめて
var block:TextBlock = new TextBlock(elem,null,null,TextRotation.ROTATE_90);
と書ける。まあこういうのはconstructorを調べればいい話。
縦書きに使うフォント
ところで、縦書きに使うフォントも調べてみた。
以下の画像で、フォントは左から
「GL-アンチックPlus」 → 「MigMix 1P」 → 「メイリオ」
MigMix 1PはAdobe製品で縦書きがおかしくなるのだが‥‥以下の例では問題ない。ダブルミニュート〝〟がおかしい。「……」「――」の位置が少しずれてるけどそれはメイリオも同じ。
GL-アンチックPlus(GL-アンチック も同じ結果だった)は、縦書きすると文字間隔がおかしい。
使ったソースコード。文章は単に縦書き文字テストのためのもので、意味はない。
package { import flash.display.Sprite; import flash.events.Event; import flash.geom.Point; import flash.text.engine.ElementFormat; import flash.text.engine.FontDescription; import flash.text.engine.TextBlock; import flash.text.engine.TextElement; import flash.text.engine.TextLine; import flash.text.engine.TextRotation; /** * ... * @author itouhiro */ [SWF(width="480",height="360",backgroundColor="0xfcfcfc",frameRate="30")] public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point var str:String = "「わかってる~!」〝ファン〟が集まり『愛♥』……? トゥリー【樹形図】をチェンジ(交換)する――。"; var font_regular:FontDescription = new FontDescription('Meiryo', 'normal'); var fmt:ElementFormat = new ElementFormat(); fmt.locale = 'ja'; fmt.fontDescription = font_regular; fmt.fontSize = 24; fmt.color = 0x333333; var elem:TextElement = new TextElement(str, fmt); var block:TextBlock = new TextBlock(); block.content = elem; block.lineRotation = TextRotation.ROTATE_90; //縦書き var offset:Point = new Point(480 - 24, 0); //textblockの左上端s displayVerticalText(block, offset); block = new TextBlock( new TextElement(str, new ElementFormat( new FontDescription('MigMix 1P', 'normal'), 24, 0x333333)), null, null, TextRotation.ROTATE_90 ); offset.x = 320 - 24; offset.y = 0; displayVerticalText(block, offset); block = new TextBlock( new TextElement(str, new ElementFormat( new FontDescription('GL-AntiquePlus', 'normal'), 24, 0x333333)), null, null, TextRotation.ROTATE_90 ); offset.x = 160 - 24; offset.y = 0; displayVerticalText(block, offset); } private function displayVerticalText(block:TextBlock, offset:Point):void { var width:int = 360 - 5; //px var linespace:int = 5; //px var next:Point = new Point(0, 0); var line:TextLine = block.createTextLine(null, width); while (line !== null) { line.x = next.x + offset.x; line.y = next.y + offset.y; next.x -= line.ascent + line.descent + linespace; //縦書きのとき trace('line.ascent='+line.ascent+', line.descent'+line.descent); addChild(line); //実行しないと画面を更新しない line = block.createTextLine(line, width); } } } }