From 455c38e8c60081a4d7d70b4b0a7997ea2d79fd24 Mon Sep 17 00:00:00 2001 From: eto Date: Thu, 20 Mar 2003 07:27:38 +0000 Subject: [PATCH] add QuadraticPath renderer --- src/kage.rb | 101 +++++++++++++++++++++++++++++++++++++++++++++++---------- src/stroke.rb | 3 -- 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/src/kage.rb b/src/kage.rb index 315b167..006d810 100755 --- a/src/kage.rb +++ b/src/kage.rb @@ -14,34 +14,101 @@ require 'singleton' # module StrokeFont + class QuadraticPath #======================================================================動的な分割に対応できるようにする + DEFAULT_DIVIDE = 4 + def initialize(p1, p2, p3) + @p1, @p2, @p3 = p1, p2, p3 + @num = DEFAULT_DIVIDE + end + def divide_adaptic #適応的分割数をする。 + end + def divide() + divide_num(@num) + end + def divide_num(num) #分割数を指定できる + #p [num] + x1, y1 = @p1 + x2, y2 = @p2 + x3, y3 = @p3 + #2次のbezier曲線の計算式、 P(t) = (1-t)^2*P1 + 2*t*(1-t)*P2 + t^2*P3 + curve = [] + (num+1).times {|i| #ここで最後の点を含めないのがポイント。これによって次の曲線との重複が無いようにしている。 + t = (i.to_f)/num + x = (1-t)*(1-t)*x1 + 2*t*(1-t)*x2 + t*t*x3 + y = (1-t)*(1-t)*y1 + 2*t*(1-t)*y2 + t*t*y3 + curve << [x,y] + } + #p curve + return curve + end + end + + class PathResolver #====================================================================== + #M 50,540 950,255 + #M 330,50 330,900 M 330,900 Q 330,950 380,950 M 380,950 840,950 M 840,950 Q 890,950 915,850 + def initialize + reset + end + def reset + @lines = [] + @px, @py = -1, -1 + end + def parse(str) + reset + cmd = [] + str.split.each {|par| + if par.length == 1 #コマンドである + exec_cmd(cmd) if 0 < cmd.length #前のコマンドが残っていたら実行 + cmd = [par] #cmdを新規生成 + elsif par =~ /[,0-9]+/ #座標値である + sx, sy = par.split(/,/) + x, y = sx.to_i, sy.to_i + cmd << [x, y] #cmdへのargを追加 + end + } + exec_cmd(cmd) if 0 < cmd.length #前のコマンドが残っていたら実行 + @lines + end + def exec_cmd(cmd) + c = cmd.shift #先頭をとる + case c + when "M" + cmd.each {|x, y| moveto(x, y) } + when "Q" + quadratic([@px, @py], cmd.shift, cmd.shift) + end + end + def moveto(x, y) + @lines << [@px, @py, x, y] if @px != -1 + @px, @py = x, y + end + def quadratic(p1, p2, p3) + #p ['quadratic', p1, p2, p3] + qp = QuadraticPath.new(p1, p2, p3) + curve = qp.divide + curve.each {|x, y| + moveto(x, y) + } + end + end + class KageParser #====================================================================== def self.parse(svg) @strokes = Strokes.new + pr = PathResolver.new lines = svg.split(/\n/) lines.each {|line| next unless line =~ /^