[pukiwiki]
-[[無料で使えるストロークフォント KST32b, KST32ZX(作者 坂 直純さん):http://www.vector.co.jp/vpack/browse/person/an018977.html]]
–[[KST32B 極めてコンパクトなJIS第1水準漢字他のStrokeFont(KST):http://www.vector.co.jp/soft/data/writing/se119277.html]]
–[[KST32ZX 篆文,篆書風(Zhuanwen,Zhongwen-Like),漢字StrokeFont(KST):http://www.vector.co.jp/soft/win95/writing/se256880.html]]
独自形式のデータなので、Pythonへ読み込むためのモジュールを作ってみました。
サンプル
http://boxheadroom.com/wp/wp-content/uploads/2009/06/goodmorning.gif
スプラインで補間してみました。
[/pukiwiki]
[pukiwiki]
-kst.pyとして保存
-同じフォルダに、[[KST32B:http://www.vector.co.jp/soft/data/writing/se119277.html]] のデータファイルKST32B.TXTを置いてください。
-標準モジュールしか使ってないので、多分、クロスプラットフォームかと。
[/pukiwiki]
# -*- coding: utf8 -*- """ kst.py KSTストロークフォントデータを変換します 必要なファイル KST32B 極めてコンパクトなJIS第1水準漢字他のStrokeFont(KST) http://www.vector.co.jp/soft/data/writing/se119277.html KST32ZX 篆文,篆書風(Zhuanwen,Zhongwen-Like),漢字StrokeFont(KST) http://www.vector.co.jp/soft/win95/writing/se256880.html 書庫中のデータファイルKST32B.TXT KST_ZX.TXTを、 このモジュールと同じフォルダに置いてください ex) import kst kstfont=KST( kst.FONT_KST32B または kst.FONT_KST32ZX,size=32) stroke=kstfont.getstroke() stroke ... [ [[x00,y00], [x01,y01],[x02,y02]...], [[x10,y10], [x11,y11],[x12,y12]...], ...] http://boxheadroom.com/blender **** Font_format(=CSF1:CompactStrokeFont/1): **** 20(Hex) : Terminator **** 21-26,28-3F : Move to X=0--29 **** 40-5B,5E-5F : Draw to X=0--29 **** 60-7D : Next X to 0--29 **** 7E,A1-BF : Move to Y=0--31 **** C0-DF : Draw to Y=0--31 **** 27,5C,5D : Reserved(else=Term);Init=(0,0) **** Record_format<+Column#>: **** < 1..4 6.........max=155 > **** 9999 (font-def) : 9999=HexAddr, (font-def)=CSF1 """ import os,sys import copy FONT_KST32B="KST32B.TXT" FONT_KST32ZX="KST_ZX.TXT" def fopen(fname,mode="rb"): if os.path.exists(fname): return open(fname) else : p,b=os.path.split(__file__) return open(os.path.join(p,os.path.split(fname)[-1])) W,H=30,32 class KST(object): def __init__(self,fname=FONT_KST32B,size=32): self.size=size lines=fopen(fname).read().splitlines() self.debug=False self.cacheflag=False self.kst_dic=dict() for i in lines : if not i.startswith("*"): try: code,stroke=i.split() self.kst_dic[int(code,16)]=stroke except: pass def getstroke(self,ch,size=None): if not size : size=self.size #sc=size/32. debug=self.debug cacheflag=self.cacheflag if cacheflag: stroke=self.cache.get(ch,[]) if stroke : print "cache" return stroke else : stroke=Stroke() dat=self.kst_dic.get(utf2jis(ch),"!~") #dat=kst_dic.get(ch[0],[]) if dat and debug :print dat.encode("hex") x=y=x0=y0=0 for j in dat: c=ord(j) if debug :print hex(c), if c in [0x27,0x5c,0x5d] : #Reserved continue elif 0x21<=c<=0x26 or 0x28<=c<=0x3f : #21-26,28-3F : Move to X=0--29 x0=x=c-0x21 if c>0x26 :x-=1 if debug : print "x=%02x"%x elif 0x40<=c<=0x5b or 0x5e<=c<0x5f : #40-5B,5E-5F : Draw to X=0--29 x0=x x=c-0x40 if c>0x5b : x-=2 self._draw(stroke,x0,y0,x,y) x0,y0=x,y if debug : print "draw x=%02x"%x elif 0x60<=c<=0x7d : #60-7D : Next X to 0--29 x0=x x=c-0x60 if debug : print "next x=%02x"%x elif c==0x7e : #7E,A1-BF : Move to Y=0--31 y0=y=H-1 if debug : print "y=%02x"%y elif 0xa1<=c<=0xbf : #7E,A1-BF : Move to Y=0--31 y=(c-0xa1+1) y0=y=H-y-1 if debug : print "y=%02x"%y elif 0xc0<=c<=0xdf : #C0-DF : Draw to Y=0--31 y0=y y=c-0xc0 y=H-y-1 self._draw(stroke,x0,y0,x,y) x0,y0=x,y if debug : print "draw y=%02x"%y stroke=resize(stroke,size) if debug :print stroke if cacheflag: cache[ch]=stroke if debug: print ch,getwidth(stroke) return stroke def _draw(self,stroke,x0,y0,x,y): if not stroke : stroke.append([ [x0,y0],[x,y]]) else : px0,py0=stroke[-1][-1] if [x0,y0]==[px0,py0]: stroke[-1].append([x,y]) else : stroke.append([[x0,y0],[x,y]]) def resize(self,stroke,size=32): sc=size/float(self.size) return scale(stroke,sc) class Stroke(list): def __new__(self): return list.__new__(self) def __init__(self,s=[],size=32): self.size=size list.__init__(self,s) def copy(self): return copy.deepcopy(self) def move(self,dx,dy): return move(self,dx,dy) def resize(self,size=32): return resize(self,size) def scale(self,scale_=(1.,1.)): return scale(self,scale_) def getwidth(self): return getwidth(self) def move(stroke,dx,dy): stroke=stroke.copy() for s in stroke : for i,(x,y) in enumerate(s) : s[i]=[x+dx,y+dy] return stroke def resize(stroke,size=32): sc=size/stroke.size ret=scale(stroke,sc) ret.size=size return ret def scale(stroke,scale=(1.,1.)): "scale=n or scale=(m,n)" stroke0=stroke stroke=stroke.copy() t=type(scale) if t==int or t==float : scx=scy=scale elif t==tuple or t==list: scx,scy=scale for s in stroke : for i,(x,y) in enumerate(s) : #s[i]=int(x*scx),int(y*scy) s[i]=x*scx,y*scy stroke.size=stroke0.size*scy return stroke def getwidth(stroke): try: px=[ p[0] for plist in stroke for p in plist] w=max(px) #w-=min(px) except: w=16 w= 16 if w<=0 else w return w debug=True def utf2jis(s): """http://www.unixuser.org/~euske/doc/kanjicode/index.html EUC 漢字コードは JIS 漢字コードの 2バイトのそれぞれの 第7ビット目を 1にしてある だけなので (0x21 → 0xA1, 0x7E → 0xFE となる)、 第7ビット目を 立てれば EUC になるし、おろせば JIS になるのである。 ただし例外は EUC で使われている半角カナ """ jislist=[ord(i)&0x7f for i in s.encode("euc-jp")] c=0 for i in jislist: c<<=8 c+=i return c last="" idx=0 def testtk(): kst=KST("KST32B.TXT",size=1.) repr(u"あ".encode("sjis").encode("hex")) last="" def drawtext(event): global last,idx s=entry.get() if not s : last="" cv.delete("line%s"%idx) return if last==s : return cv.delete("line%s"%idx) idx+=1 x_=y_=10 for c in s: stroke=kst.getstroke(c,size=1.) stroke=scale(stroke,(32,32)) sw=getwidth(stroke)+4 stroke=move(stroke,x_,y_) for ln in stroke: if not ln : continue x0,y0=ln[0] if False : for x,y in ln[1:] : cv.create_line(10+x0,y0,10+x,y, tags ="line%s"%idx,smooth=True ) cv.create_line(*ln,**dict(tags ="line%s"%idx, width=1,smooth=True)) x_+=sw last=s root=tk.Tk() label0 = tk.Label(root, text=u'ここに入力') entry=tk.Entry(root) entry.bind("<KeyRelease>",drawtext) cv=tk.Canvas(width=640,height=400,background="white") for i in label0,entry,cv : i.pack() return root if __name__=="__main__": import Tkinter as tk root=testtk() root.mainloop()
なんか、汚いコードですが、紛失しないようにblogにもメモ
[pukiwiki]
オマケ
http://boxheadroom.com/wp/wp-content/uploads/2009/06/x3.gif
ネタ元 [[スコトプリゴニエフスク通信:http://d.hatena.ne.jp/perezvon/20090601/1243872974]]
[/pukiwiki]