適当なRubyのお絵描きツール
Postscriptを出力できます。Postscriptしか出力できません。
線の補正とかしようかと思ったけどめんどかったので相当やる気無い方法になってます。
忘れてた
保存ダイアログはEnterキーで呼び出します。
Ruby/Tkの方の線の表示が汚ないのは仕様です。
ActiveScriptRuby 1.8.6 + ActiveTcl 8.4.16.1 で動作確認。
以下ソース
#!/usr/bin/ruby require "tk" class Point def initialize(x, y) @x = x @y = y end def x @x end def y @y end end class TkcCurveLine def initialize(parent, x, y) @parent = parent @points = [Point.new(x, y)] @lines = [] @width = 5 end def appendPoint(x, y) prevpt = @points[-1] point = Point.new(x, y) @points.push(point) line = TkcLine.new(@parent, prevpt.x, prevpt.y, x, y) line.width = @width @lines.push(line) end def reshape newpoints = [] for i in 0..(@points.length-1) if(i>0 && i<@points.length-1) prevpt = @points[i-1] nextpt = @points[i+1] newpt = Point.new((prevpt.x+nextpt.x)/2, (prevpt.y+nextpt.y)/2) newpoints.push(newpt) else newpoints.push(@points[i]) end end @points = newpoints repaint end def repaint delete prevpt = false @points.each{|p| if(prevpt) line = TkcLine.new(@parent, prevpt.x, prevpt.y, p.x, p.y) line.width = @width @lines.push(line) end prevpt = p } end def delete @lines.each{|line| line.delete } end def to_psseg seg = "" @points.each{|p| if(seg=="") seg += sprintf("%d %d moveto\n", p.x, p.y) first = false else seg += sprintf("%d %d lineto\n", p.x, p.y) end } seg += sprintf("%d setlinewidth\n", @width) seg += "stroke\n" seg end end class TkPaintCanvas < TkCanvas def initialize super self.bg = "white" @press = false @lines = [] self.bind("Motion", proc{|x, y| mouseMotion(x, y)}, "%x %y") self.bind("ButtonPress", proc{|x, y| mousePress(x, y)}, "%x %y") self.bind("ButtonRelease", proc{|x, y| mouseRelease(x, y)}, "%x %y") end def mouseMotion(x, y) if(@press) mouseDrag(x, y) end end def mouseDrag(x, y) @curve.appendPoint(x, y) end def mousePress(x, y) @press = true @curve = TkcCurveLine.new(self, x, y) end def mouseRelease(x, y) @curve.reshape @lines.push(@curve) @press = false end def saveImage savepath = Tk.getSaveFile("defaultextension"=>".eps") pssegs = "%!PS-Adobe-3.0 EPSF-3.0\n" pssegs += sprintf("%%%%BoundingBox: 0 0 %d %d\n", self.width, self.height) pssegs += sprintf("0 %d translate 1 -1 scale\n", self.height) pssegs += "newpath\n" if(savepath!="") @lines.each{|line| pssegs += line.to_psseg } File.open(savepath, "w"){|file| file.print(pssegs) } end end end canvas = TkPaintCanvas.new canvas.pack rootResize = proc{|w, h| canvas.width = w-4 canvas.height = h-4 } Tk.root.bind("Configure", rootResize, "%w %h") Tk.root.bind("Return", proc{canvas.saveImage}) Tk.mainloop
rootResizeのw-4の4ってなんでしょうね。俺にもよくわかりません。
そうしないとキャンバスがどんどんおっきくなっちゃったので。なんかもっと良い方法は絶対あるはずだけどめんどいので。
Postscriptとか全然憶えてなくて困った。