Quantcast
Channel: itouhiroはてなブログ
Viewing all articles
Browse latest Browse all 107

ActionScript3.0でテキストを縦書きする

$
0
0

動作確認環境

  • 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でも簡単に導入・使用できるらしい。

この記事を参考に、学んでみる。



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);
            }
        }
    }
}

こんなソースをコンパイルすると、以下のような実行画面になる。
f:id:itouhiro:20130426081637p:plain

最初の行が欠けてる。


原因はTextBlockの左上端 (0,0) はフォントのベースラインの位置になるからのようだ。
f:id:itouhiro:20130426083623p:plain

だから

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);

f:id:itouhiro:20130426085528p:plain


半角英数字と全角文字の切り替わる行で、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」 → 「メイリオ

f:id:itouhiro:20130426132337p:plain


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);
            }

        }
    }
}







 


Viewing all articles
Browse latest Browse all 107

Trending Articles