ruby版jabanner

ruby + cairoで作ってみた。
思った以上に楽。

jabanner同様X非依存なのです

rubyのcairoまわりは微妙に資料が少ない気がしないでもない気がしないでもない。

#!/usr/bin/env ruby

require "rubygems"
gem "cairo"
require "cairo"
require "optparse"

fontName = "ヒラギノ明朝 Pro W6"
fontSize = 20
chars = "#MND80Z7I?+=~:,. "
margin = [1,1,1,1]
outline = false

#引数処理
opt = OptionParser.new
opt.on( "-c", "--chars=CHARS", "アンチエイリアスの使う文字列[\"#{chars}\"]" )	{|v| chars = v }
opt.on( "-f", "--font=FONT", "フォント[\"#{fontName}\"]" )			{|v| fontName = v }
opt.on( "-o", "--[no-]outline", "白抜き表示する" )				{|v| outline = v }
opt.on( "-s", "--size=SIZE", "フォントサイズ[\"#{fontSize}\"]" )		{|v| fontSize = v.to_i }
opt.parse!( ARGV )
#FIXME: Cairoは改行文字を読み込まないらしい
string = ARGV.join( "\n" )

#領域計算用のsurface,context
tmpSurface = Cairo::ImageSurface.new( 0, 0 )
tmpContext = Cairo::Context.new( tmpSurface )

#表示する文字の領域を得る
tmpContext.set_font_size( fontSize ).select_font_face( fontName, 0, 0 )
ext = tmpContext.text_extents( string )

width = ext.width + margin[1] + margin[3]
height = ext.height + margin[0] + margin[2]

#surface, contextを新たに作る。
surface = tmpSurface.create_similar( tmpSurface.content , width, height )
context = Cairo::Context.new( surface )

#背景を塗りつぶす
context.set_source_rgb( 1, 1, 1 ).rectangle( 0, 0, width, height ).fill

#文字列を描画する
context.set_font_size( fontSize ).select_font_face( fontName, 0, 0 ).set_source_rgb( 0, 0, 0 )
context.move_to( -ext.x_bearing + margin[3], -ext.y_bearing + margin[0] )
context.line_width = 0.5
if outline then
	context.text_path( string ).stroke
else
	context.show_text( string )
end

#jabanner化
0.upto( height - 1 ) {|y|
	0.upto( width - 1 ) {|x|
		bb = surface.data[4*(x + y*width) + 0]
		gg = surface.data[4*(x + y*width) + 1]
		rr = surface.data[4*(x + y*width) + 2]

		yy = (rr * 0.299 + gg * 0.587 +  bb * 0.114)
		putc chars[chars.length * yy / 256]
	}
	putc "\n"
}
surface.finish

オプション等はc++ + gd版に比べるのオプション少なめですが、眠くなったのでここまで。
多分どっかのrubyerのid:viverがなにかやってくれるさ(何

いや、時間とやる気とノリがあれば後で実装します。



例のごとくpartty.orgで