From c491901e11d307930d601e308e28324d4d81c54a Mon Sep 17 00:00:00 2001 From: eto Date: Wed, 12 Mar 2003 08:33:49 +0000 Subject: [PATCH] add kage.rb, kageserver.rb, csf.rb, stroke.rb --- src/csf.rb | 121 ++++++++++++++++++++++++++ src/kage.rb | 98 +++++++++++++++++++++ src/kageserver.rb | 142 ++++++++++++++++++++++++++++++ src/stroke.rb | 251 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 612 insertions(+) create mode 100755 src/csf.rb create mode 100755 src/kage.rb create mode 100755 src/kageserver.rb create mode 100755 src/stroke.rb diff --git a/src/csf.rb b/src/csf.rb new file mode 100755 index 0000000..c323495 --- /dev/null +++ b/src/csf.rb @@ -0,0 +1,121 @@ +#!/usr/bin/env ruby +# CSF module by eto 2002-1115 + +require 'sgl' +require 'kconv' +require 'uconv' + +module StrokeFont + CSF_FONT_DIR = 'd:/work/chise/csf/' + CSF_DEFAULT_FILE = 'KST32B.CSF1' + CSF_KOUKOTSU_FILE = 'KST32ZX.CSF1' + + class CSFStrokeMaker #====================================================================== + DEST_WIDTH = 1000 #‘å‚«‚³‚ð‚¨‚¨‚æ‚»1000x1000‚ɐ³‹K‰»‚·‚éB + ORG_WIDTH = 32 #Œ³‚̃TƒCƒY‚́A‰¡30~c32 + def initialize + @x, @y, @nx, @ny = 0, 0, 0, 0 + @strokes = Strokes.new + end + attr_reader :strokes + def move_to_x(x) @x = x; @nx = x; end + def draw_to_x(x) @nx = x; drawline; @x = @nx; @y = @ny; end + def next_x_to(x) @nx = x; end + def move_to_y(y) @y = y; @ny = y; end + def draw_to_y(y) @ny = y; drawline; @x = @nx; @y = @ny; end + def drawline() + @strokes.add_line(t(@x), t(@y), t(@nx), t(@ny)) + end + def t(a) a*DEST_WIDTH/ORG_WIDTH; end + end + + class CSFParser #====================================================================== + def self.parse(str) #Strokes‚ð•Ô‚· + return Strokes.new if str == nil + sm = CSFStrokeMaker.new + (0...str.length).each {|i| + n = str[i] + if 0x21 <= n && n <= 0x26 + sm.move_to_x(n - 0x21) + elsif 0x28 <= n && n <= 0x3f + sm.move_to_x(n - 0x28 + 6) + elsif 0x40 <= n && n <= 0x5b + sm.draw_to_x(n - 0x40) + elsif 0x5e <= n && n <= 0x5f + sm.draw_to_x(n - 0x5e + 28) + elsif 0x60 <= n && n <= 0x7d + sm.next_x_to(n - 0x60) + elsif 0x7e == n + sm.move_to_y(n - 0x7e) + elsif 0xa1 <= n && n <= 0xbf + sm.move_to_y(n - 0xa1 + 1) + elsif 0xc0 <= n && n <= 0xdf + sm.draw_to_y(n - 0xc0) + end + } + return sm.strokes + end + end + + class CSFGlyph #====================================================================== + def initialize(code, stroke) + @code = code + @stroke_str = stroke + @strokes = nil + end + attr_reader :strokes + def parse() + return if @strokes + @strokes = CSFParser.parse(@stroke_str) + end + def init + parse if @strokes.nil? + end + end + + class CSFFont #====================================================================== + def initialize(file=CSF_DEFAULT_FILE) + @file = CSF_FONT_DIR + file + @glyphs = [] + read_file + @rend = nil + @rend = StrokesRenderer.new + @rend.hsv = [50, 100, 100] + end + def read_file() + open(@file) {|f| + while(line = f.gets) + next if line =~ /^\*/ + c, s = line.split + code = c.hex #JIS‚Ì’l‚ª”’l‚Å‚Í‚¢‚é + @glyphs[code] = CSFGlyph.new(code, s) + end + } + end + def init(code) + glyph = @glyphs[code] + return if glyph == nil + glyph.init() + glyph.parse + @rend.set_strokes(glyph.strokes) + end + def draw(code) #ˆø”‚É‚ÍJIS‚𐔒l‰»‚µ‚½‚à‚Ì‚ª‚Í‚¢‚é + glyph = @glyphs[code] + return if glyph == nil + @rend.draw + end + def print(code) + jis = JISX0208.new + char = jis.get_char(code) + printf("[%s][%04x]\n", char.nil? ? "nil" : char.map_sjis, code) + end + def ucs_to_jis(ucs) + char = Character.get(ucs) + j = char.japanese_jisx0208 + return j + end + end + +end + +#----------------------------------------------------------------------I—¹ diff --git a/src/kage.rb b/src/kage.rb new file mode 100755 index 0000000..2c4baf1 --- /dev/null +++ b/src/kage.rb @@ -0,0 +1,98 @@ +#!/usr/bin/env ruby +# KageFont library by eto 2003-0311 + +require 'sgl' +require 'kageserver' + +#こんな感じのフォーマットになっている。 +# +# +# +# +# +# + +module StrokeFont + class KageParser #====================================================================== + def self.parse(svg) + @strokes = Strokes.new + lines = svg.split(/\n/) + lines.each {|line| + next unless line =~ /^/) + end + def read_list + h = {} + open("kage-list.txt"){|f| + while line = f.gets + if line =~ /u([0-9a-f]+)\.skeleton/ + code = $1 + num = code.hex + error = false + error = true if line =~ /error/ + h[num] = error + end + end + } + return h + end + def get_all + #error_h = read_list + STDOUT.binmode + @kn = KanjiNetwork.new + @kl = KanjiList.instance + #list = @kl.awase(0) + #list = @kl.awase(1) + list = @kl.joyo + @kn.make_network(list) + nodes, edges = @kn.nodes_and_edges + ar = [] + nodes.each {|ch| + char = ch.char + num = char.to_i + #next if 0xffff < num + ar << num + } + get_ar(ar) + end + def get_ar(ar) + ar.each {|num| #intの数列 + char = Character.get(num) + ch = char.to_s + er = char.to_er + #TYPES.each_with_index {|type, index| + #(0..2).each {|index| + (0..0).each {|index| + result = get(num, index) #cacheに保存するべしと。 + next if result + err = "error" + print "#{er} #{ch} #{err}\n" + } + } + end + def test_kanji + char = "&CDP-8BA5;".de_er + #p char.inspect_all + #str = (char.to_s+"真") + str = (char.to_s+"直") + p str.find + end +end + +if $0 == __FILE__ #====================================================================== + ks = KageServer.instance + #print ks.get(0x4e03) + ks.get_all +end + +#----------------------------------------------------------------------end. diff --git a/src/stroke.rb b/src/stroke.rb new file mode 100755 index 0000000..b6f379b --- /dev/null +++ b/src/stroke.rb @@ -0,0 +1,251 @@ +#!/usr/bin/env ruby +# StrokeFont library by eto 2003-0311 + +require 'sgl' +require 'kage' +require 'csf' + +module StrokeFont + class StrokesRenderer #====================================================================== + def initialize + @start_time = nil + @strokes = nil + @hsv = [0, 0, 100] + init + end + attr_accessor :hsv + def init() @start_time = Time.now; end + def set_strokes(strokes) + @strokes = strokes + init + end + def draw + @strokes.strokes.each_with_index {|stroke, index| + draw_delay(stroke, index) + } + end + def draw_alpha(stroke, time) + px, py = 0, 0 + span = 0.1 + time += span*2 + stroke.points.each {|x, y| + a = time / span + colorHSV(@hsv[0], @hsv[1], @hsv[2], a*100.0) + line(px, py, x, y) if (px != 0 || py != 0) #最初の点ではない + px, py = x, y + time -= span + } + end + def draw_delay(stroke, index) + now = Time.now + @start_time = Time.now if @start_time == nil + diff = now - @start_time #開始からの秒数がはいる + draw_alpha(stroke, diff - index*0.3) + end + end + + class Stroke #====================================================================== 一本の線 + def initialize + @points = [] + @length = nil + end + attr_reader :points + def add_point(x, y) + @points << [x, y] + end + def length #未チェック + return @length if @length + len = 0.0 + px, py = -1, -1 + @points.each {|x, y| + if px != -1 + len += Math.sqrt((x-px)*(x-px)+(y-py)*(y-py)) + end + px, py = x, y + } + @length = len + return @length + end + end + + class Strokes #====================================================================== 複数の線 + def initialize + @strokes = [] + @px1, @py1, @px2, @py2 = 0, 0, 0, 0 + @x1, @y1, @x2, @y2 = 0, 0, 0, 0 + @px, @py = -1, -1 + end + attr_reader :strokes + def add_line(x1, y1, x2, y2) + if (@px != x1 || @py != y1) #以前の点とつながっていなかったら、 + @strokes << Stroke.new + @strokes.last.add_point(x1, y1) + end + @strokes.last.add_point(x2, y2) + @px, @py = x2, y2 + end + end + + class CodeSelector #====================================================================== + WIDTH, HEIGHT = 256, 256 + SCALE = 2 + def initialize(cx=0, cy=0) + @cx, @cy = cx, cy + @s = SCALE + @x1, @y1 = @cx-@s*WIDTH/2, @cy-@s*HEIGHT/2 + @x2, @y2 = @cx+@s*WIDTH/2, @cy+@s*HEIGHT/2 + @px, @py = @cx, @cy #とりあえず中心が開始点 + @pw, @ph, @pr = 30, 30, 10 + @dragging = false + @onkeydown = false + @code = 0 + calc_code + end + attr_reader :code + def draw + colorHSV(0, 0, 100, 10) #まずは下敷きになる枠を書きます。 + rect(@x1, @y1, @x2, @y2) + lineWidth(1) + colorHSV(0, 0, 100, 50) + b = 8; s = @s*WIDTH/b + (0..b).each {|n| + line(@x1, @y1+n*s, @x2, @y1+n*s) + line(@x1+n*s, @y1, @x1+n*s, @y2) + } + colorHSV(0, 100, 100, 100) # 次にポインターを書きます + circle(@px, @py, @pr) + line(@px-@pw/2, @py, @px+@pw/2, @py) + line(@px, @py-@ph/2, @px, @py+@ph/2) + end + def onMouse(x, y) + if @onkeydown + x, y = @px, @py + end + if @dragging || @onkeydown + @onkeydown = false + @px, @py = x, y #p [x, y] + @px = @x1 if @px < @x1 + @py = @y1 if @py < @y1 + @px = @x2-1 if @x2-1 < @px + @py = @y2-1 if @y2-1 < @py + return calc_code + else + return false + end + end + def calc_code() + x = ((@px - @x1)/@s).to_i + y = HEIGHT-1 - ((@py - @y1)/@s).to_i + code = x + y*WIDTH + if @code != code + @code = code + return true #changed + #p [x, y, code] + printf("%02x %02x %04x\n", x, y, @code) + else + return false + end + end + def show_list(list) + colorHSV(0, 100, 100, 100) + list.each {|code| + x, y = code_to_xy(code) + rect(x, y, x+2, y-2) + } + end + def code_to_xy(code) + cx = code % WIDTH + cy = HEIGHT - (code / WIDTH) #intになる? + x = cx * SCALE + @x1 + y = cy * SCALE + @y1 + return x, y + end + def length(x, y) Math.sqrt(x*x + y*y) end + def onMouseDown(x, y) + if length(@px-x, @py-y) < @pr + @dragging = true + end + end + def onMouseUp(x, y) @dragging = false end + def onKeyDown(key) + @onkeydown = true + case key + when 273 + @py += @s + when 274 + @py -= @s + when 276 + @px -= @s + when 275 + @px += @s + end + end + end + +end + +if $0 == __FILE__ #====================================================================== + $LOAD_PATH << '../ruby/src' + require 'chise' + include CHISE + require 'stroke' + include StrokeFont + + def setup + useSmooth() + window(-300,-300,300,300) + background 0,0,20 + useFramerate(30) + @cs = CodeSelector.new + @csf1 = CSFFont.new() #普通の文字 + @csf2 = CSFFont.new(CSF_KOUKOTSU_FILE) #甲骨文字 + @key = 1 + @kage = KageFont.new() + @changed = nil + end + + def display + @changed = @cs.onMouse(mouseX, mouseY) #変化があったか? + @cs.draw + @cs.show_list(@kage.cache_list) + code = @cs.code + + push + scale 0.2 + translate -500,-500 + lineWidth(2) + draw_kage(code) + draw_csf(code) + pop + end + + def draw_kage(code) + char = Character.get(code) + return if char.nil? + @kage.init(code) if @changed + @kage.print(code) if @changed + @kage.draw(code) + end + + def draw_csf(ucs) + char = Character.get(ucs) + return if char.nil? + j = char.japanese_jisx0208 + return if j.nil? + code = j + csf = @key == 1 ? @csf1 : @csf2 + csf.init(code) if @changed + csf.print(code) if @changed + csf.draw(code) + end + + def onMouseDown(x, y) @cs.onMouseDown(x, y)end + def onMouseUp(x, y) @cs.onMouseUp(x, y)end + def onKeyDown(key) + @key = key + @cs.onKeyDown(key) + end + mainloop +end + +#----------------------------------------------------------------------end. -- 1.7.10.4