PlaggerでSWF 好きなフォントでFeedを読む
PlaggerでSWFファイルを出力するプラグイン(Plagger::Plugin::Publish::SWF)を作成してみました。SWF::Builderを使い指定したフォントでFeedを表示しています。
プラグインはPlagger::Plugin::Publish::PDFを参考にしました。初めてでしたが、結構簡単に作れました。Plaggerバンザイです。以下注意点。
- SWF::Builderに渡す日本語にはUnicodeフラグをつける(文字化けします)
- 文字の表示はActionScriptで操作(Perlと混ざるとややこしい)
- 改行の処理
3番目の改行の処理ではJcodeのjfold()を使って指定した最大文字数で改行しています。自動改行するためにダイナミックテキストを使用するとフォントをSWFに埋め込まなければならないので、ファイルサイズが非常に大きくなります。改行コードを埋め込んでスタティックテキストとして処理しました。
以下config.yamlとソースです。
- module: Publish::SWF config: dir: swf font: HONYA-JI.ttf color: ff0084 width: 500 height: 500 linefeed: 30 bgcolor: ffffff title_size: 32 body_size: 24
package Plagger::Plugin::Publish::SWF; use strict; use base qw(Plagger::Plugin); use File::Spec; use SWF::Builder; use Jcode; sub register{ my ($self,$context) = @_; $context->register_hook( $self, 'publish.feed' => \&feed, ); } sub feed{ my ($self,$context,$args) = @_; my $dir = $self->conf->{dir}; unless (-e $dir && -d _) { mkdir $dir, 0755 or $context->error("mkdir $dir: $!"); } my $file = File::Spec->catfile($dir, $args->{feed}->id . ".swf"); my $id = $args->{feed}->id; my $movie = $self->create_stage($context,$args); $movie->save($file); return; } sub convert{ my ($self, $str) = @_; utf8::decode($str) unless utf8::is_utf8($str); return $str; } sub create_stage{ my ($self,$context,$args) = @_; my $bgcolor = $self->conf->{bgcolor}; my $width = $self->conf->{width}; my $height = $self->conf->{height}; my $movie = SWF::Builder->new ( FrameRate => 12, FrameSize => [0, 0,$width,$height], BackgroundColor => $bgcolor ); $movie->frame_action(1)->compile( <<AS_END ); this.page=0; nextPage(); _root.pre_mc._visible=false; function nextPage(){ var title_name = 'title_text' + this.page.toString(); var entry_name = 'entry_text' + this.page.toString(); this[title_name].onEnterFrame=function(){} this[title_name]._alpha=0; this[title_name]._visible=false; this[entry_name].onEnterFrame=function(){} this[entry_name]._alpha=0; this[entry_name]._visible=false; this.page++; entry_name = 'entry_text' + this.page.toString(); title_name = 'title_text' + this.page.toString(); if(!this[entry_name]){ this.page=1; entry_name = 'entry_text' + this.page.toString(); title_name = 'title_text' + this.page.toString(); } this[entry_name].onEnterFrame=function(){ this._alpha+=6; this._visible=true; } this[title_name].onEnterFrame=function(){ this._alpha+=6; this._visible=true; } } AS_END my $new_mc = $movie->new_movie_clip; my $shape = $new_mc->new_shape; $shape->fillstyle($bgcolor); $shape->lineto(0,0)->lineto(0,$height)->lineto($width,$height)->lineto($width,0)->lineto(0,0); $shape->place; my $new_mc_ins = $new_mc->place; $new_mc_ins->on('Press')->compile('_root.nextPage();'); my $new_pre_mc = $movie->new_movie_clip; my $pre_shape = $new_pre_mc->new_shape; $pre_shape->fillstyle($self->conf->{color}); $pre_shape->lineto(0,0)->lineto(0,$height)->lineto($width,$height)->lineto($width,0)->lineto(0,0); $pre_shape->place; $new_pre_mc->place->name('pre_mc'); my $page=0; for my $entry ($args->{feed}->entries) { $page++; $self->create_page($movie,$page,$entry->title,$entry->body); } $movie; } sub create_page(){ my ($self,$movie,$page,$title,$body) = @_; my $font = $self->conf->{font}; my $color = $self->conf->{color}; my $title_size = $self->conf->{title_size}; my $body_size = $self->conf->{body_size}; $title = $self->convert($title); $body =~ s/<.+?>//g; $body = $self->linefeed($body); $body = $self->convert($body); my $entry_name = 'entry_text'.$page; my $title_name = 'title_text'.$page; my $font = $movie->new_font($font); my $title_text_mc = $movie->new_movie_clip; my $title_ins = $title_text_mc->new_static_text($font); $title_ins->size($title_size)->color($color)->text($title)->place; my $title_text_ins = $title_text_mc->place; $title_text_ins->on('Load')->compile('this._visible=false;this._alpha=0;'); $title_text_ins->name($title_name); $title_text_ins->moveto(10,10); my $entry_text_mc = $movie->new_movie_clip; my $entry_ins = $entry_text_mc->new_static_text($font); $entry_ins->size($body_size)->color($color)->text($body)->place; my $entry_text_ins = $entry_text_mc->place; $entry_text_ins->name($entry_name); $entry_text_ins->on('Initialize')->compile('this._visible=false;this._alpha=0;'); $entry_text_ins->moveto(10,50); } sub linefeed{ my ($self,$str,$n)=@_; my $linefeed = $self->conf->{linefeed}; my @line = split "\n",$str; my $line; for my $l (@line){ my @l = Jcode->new($l)->jfold($linefeed); $line .= join "\n",@l; $line .= "\n"; } $line; } 1; __END__