2012/01/04

Recent entries from same category

  1. clangd を使う時に便利なコマンド compiledb
  2. VimConf 2018 に行ってきた。
  3. Software Design 2018年7月号「Vim 絶対主義」の執筆に参加しました。
  4. Vim の :terminal の中から外の Vim を操る方法
  5. Vim と日本語入力の話。

まず中平さんの vim-paint をインストール。
ynkdir/vim-paint - GitHub
https://github.com/ynkdir/vim-paint
このままだと日本語出せないのでパッチを当てる。
diff --git a/autoload/paint/bdf.vim b/autoload/paint/bdf.vim
index 8485995..e8323b8 100644
--- a/autoload/paint/bdf.vim
+++ b/autoload/paint/bdf.vim
@@ -139,6 +139,98 @@ let s:font.hexbits = [
       \ [1, 1, 1, 1],
       \ ]
 
+let s:utf8len = [
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+\ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+\ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,0,0,
+\]
+
+function! s:dec2bin(v)
+  let v = a:v
+  if v == 0 | return 0 | endif
+  let ret = ""
+  while v > 0
+    let i = v % 2
+    let ret = i . ret
+    let v = v / 2
+  endwhile
+  return ret
+endfunction
+
+function! s:bin2dec(v)
+  let v = a:v
+  if len(v) == 0 | return 0 | endif
+  let i = 1
+  let ret = ""
+  for n in reverse(split(v, '\zs'))
+    if n == 1
+      let ret = ret + i
+    endif
+    let i = i * 2
+  endfor
+  return ret
+endfunction
+
+function! s:bitshift(a,b)
+  let a = s:dec2bin(a:a)
+  let a = repeat('0', 32-len(a)) . a
+  if a:b < 0
+    let a = (repeat('0', -a:b) . a[: a:b-1])[-32:]
+  elseif a:b > 0
+    let a = (a . repeat('0', a:b))[-32:]
+  endif
+  return s:bin2dec(a)
+endfunction
+
+function! s:bitand(a,b)
+  let a = s:dec2bin(a:a)
+  let b = s:dec2bin(a:b)
+  return s:bin2dec(tr((a + b), '21', '10'))
+endfunction
+
+function! s:byte2code(byte)
+  let p = a:byte
+  let n0 = char2nr(p[0])
+  if n0 < 0x80
+    return n0
+  endif
+  let l = s:utf8len[n0]
+  let n1 = char2nr(p[1])
+  if l > 1 && s:bitand(n1, 0xc0) == 0x80
+    if l == 2
+      return s:bitshift(s:bitand(n0, 0x1f), 6) + s:bitand(n1, 0x3f)
+    endif
+    let n2 = char2nr(p[2])
+    if s:bitand(n2, 0xc0) == 0x80
+      if l == 3
+        return s:bitshift(s:bitand(n0, 0x0f), 12) + s:bitshift(s:bitand(n1, 0x3f), 6) + s:bitand(n2, 0x3f)
+      endif
+      let n3 = char2nr(p[3])
+      if s:bitand(n3, 0xc0) == 0x80
+        if l == 4
+          return s:bitshift(s:bitand(n0, 0x07), 18) + s:bitshift(s:bitand(n1, 0x3f), 12) + s:bitshift(s:bitand(n2, 0x3f), 6) + s:bitand(n3, 0x3f)
+        endif
+        let n4 = char2nr(p[4])
+        if s:bitand(n4, 0xc0) == 0x80
+          if (l == 5)
+            return s:bitshift(s:bitand(n0, 0x03), 24) + s:bitshift(s:bitand(n1, 0x3f), 18) + s:bitshift(s:bitand(n2, 0x3f), 12) + s:bitshift(s:bitand(n3 & 0x3f), 6) + s:bitand(n4, 0x3f)
+          endif
+          let n5 = char2nr(p[5])
+          if s:bitand(n5, 0xc0) == 0x80 && l == 6
+            return s:bitshift(s:bitand(n0, 0x01), 30) + s:bitshift(s:bitand(n1, 0x3f), 24) + s:bitshift(s:bitand(n2, 0x3f), 18) + s:bitshift(s:bitand(n3, 0x3f), 12) + s:bitshift(s:bitand(n4, 0x3f), 6) + s:bitand(n5, 0x3f)
+          endif
+        endif
+      endif
+    endif
+  endif
+  return n0
+endfunction
+
 "
 " |hello, world
 " +------------
@@ -146,7 +238,8 @@ let s:font.hexbits = [
 " origin
 function s:font.draw_text(canvas, text, org, color)
   let [ox, oy] = a:org
-  for c in map(split(a:text, '\zs'), 'char2nr(v:val)')
+  for c in map(split(a:text, '\zs'), 's:byte2code(iconv(v:val, &encoding, "utf-8"))')
+    call garbagecollect()
     if !has_key(self.glyphs, c)
       let c = self.default_char
     endif
ビットシフト関数は結構適当。最新のvimならbitwize関数が入ってるはずなので、そっちを使った方が良い。さらにunifontからbdfフォントを貰ってくる。
GNU Unifont Glyphs

This page contains the latest release of the GNU Unifont, with glyphs for every printable code point...

http://unifoundry.com/unifont.html
そしてコード
scriptencoding utf-8
let canvas = paint#canvas#new(10050)
let font = paint#bdf#loadfile(globpath(&rtp, 'font/unifont/unifont-5.1.20080820.bdf'))
let text = "あけまして"
call canvas.draw_text(text, [1020], font, [000])
let text = "おめでとう"
call canvas.draw_text(text, [1040], font, [000])

call canvas.save('kakizome.bmp')
出来上がり
vim-de-kakizome
ちなみに画像ファイル出力までに5分くらいかかります。
Posted at by | Edit


blog comments powered by Disqus