[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]