前記事からの続きです。
IVSの異体字をブログ等に書くという需要があるのか解りませんが、技術的に分かる範囲で書いておきます。
まず、フォントの話しですが、前記事に示したようなIVS対応フォントが閲覧者側の環境に存在するのか、
もしくはwebフォントを設定するかということになるでしょう。
ホームページならまだしも、ブログでwebフォントをアップロードできる環境というものは、自前サーバ以外だと数えるほどしかないだろう。
Google Web Fontsのように、アップロード不要の方法もあるかとは思うが、webフォントで、データ量の多い日本語フォントは珍しいし、更にIVS対応ということも重なっているので、状況は極めて難しいと言わざるを得ない。
そういうことを考えると、游明朝や游ゴシックというOS同梱のIVS対応フォントを使うことが有力視されるだろう。
必要によっては読者側にフォントのインストールを促すということにもなるかもしれませんね。
cssのfont-familyについて、
xxx { font-family: '游明朝', '游明朝体', 'Yu Mincho', 'YuMincho'; }
といったような、WindowsもMac OS Xも同梱されている、游明朝などに決め打ちすることになるだろう。
html内に異体字を表示するには?
html内でIVSによる異体字を表示することは、実はそれほど難しいことではありません。
入力:神󠄀
出力:神󠄀
の様に、16進数数値文字参照を使えば良い。
まぁ、IVS対応のIMEがあれば、こんな手間はないかとは思いますが、そういったアプリに頼る必要もないかもしれません。
Javascriptで異体字を表示するには?
例えば、IVS用の空間はU+E0100~U+E01EFの240個を、for文などで文字を連結し、divの中に表示するとします。
var str='';
for (var i=0xE0100; i<0xE01F0; i++) str += '邉&#x'+i.toString(16)+';';
document.getElementById('nabe').innerHTML = str;
といったように容易に出来る。
HTML5のCanvasにfillTextで描くには?
先の方法では、ブラウザが自動的にやってくれていた処理について、プログラムで解決しなければなりません。
var w=36;
ctx.font = ''+w+'px 游明朝';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'black';
var str1 = '邉', str2;
for (var i=0; i<240; i++) {
str2 = str1+unescape('%u'+(0xE0100+i).toString(16));
ctx.fillText(str2,w*(i%16)+w/2+12,w*(i>>4)+w/2+12);
}
これでは正常に表示されません。
サロゲートペアについて
そもそも、Unicodeは16進数4桁、0x0000から0xFFFFまでの65536文字で、世界のあらゆる文字を収録しようとしていたが、結局足りずに、どんどん増えてしまったという経緯があります。
U+E0100~U+E01EFは、16進数5桁なので、16進数4桁や16進数2桁のサロゲートペアに分解する必要があります。
escape/unescapeを使う
これは、UTF-16LEベースでエンコード/デコードしているようですので、
str2 = str1+unescape('%uDB40%u'+(0xDD00+i).toString(16));
サロゲートペアの計算は、先に机上でやっておく。
0xE0100 -> 1110 0000 0001 0000 0000
0xE01EF -> 1110 0000 0001 1110 1111
0xE0100-0x10000=0xD0100
0xE01EF-0x10000=0xD01EF
0xD0100 -> 11010000000100000000
0xD01EF -> 11010000000111101111
0xD800 -> 1101100000000000
0xDC00 -> 1101110000000000
1101101101000000 -> 0xDB40
1101110100000000 -> 0xDD00
1101101101000000 -> 0xDB40
1101110111101111 -> 0xDDEF
0xE0100 -> %uDB40%uDD00
0xE01EF -> %uDB40%uDDEF
IVSは240個なので、下位の8bitで事足りることが解りますね。
ただ、この関数は古い仕様なので、いずれ使えなくなることを想定しなければなりません。
encodeURI/decodeURI
encodeURIComponent/decodeURIComponent
を使う
これらは、UTF-8LEベースでエンコード/デコードしますので、
str2 = str1+decodeURIComponent('%F3%A0%'+(0x84+(i>>6)).toString(16)+'%'+(0x80+i%64).toString(16));
といったように、出来るだけ簡潔になるように考えて書いてはみたが、どんどん長くなってしまう。
0xE0100 -> 0 1110 0000 0001 0000 0000 (21bit)
0xE01EF -> 0 1110 0000 0001 1110 1111 (21bit)
0xF0 -> 11110000
0x80 -> 10000000
0x80 -> 10000000
0x80 -> 10000000
11110011 -> 0xF3
10100000 -> 0xA0
10000100 -> 0x84
10000000 -> 0x80
11110011 -> 0xF3
10100000 -> 0xA0
10000111 -> 0x87
10101111 -> 0xAF
0xE0100 -> %F3%A0%84%80
0xE01EF -> %F3%A0%87%AF
まぁ、コーディング方法は各自が考えることなので、サロゲートペアの知識が必要になるということは確かですね。
上手く行けば、Canvasには上記のような画像が表示されることだろう。
さてさて、あえてCanvas上にfillTextで描いたかというと、240文字すべてに異体字が割り振られているわけではないということ。
U+E0100から、どこまであるのかということを返してくれる関数のようなものは、自作しなければならないだろう。
Canvasに描けたのだから、getImageDataで吸い上げて、それぞれを比較するということも出来なくもない。
ご丁寧に比較しようとすると、大きく表示して、1x1ピクセル単位でRBGAのそれぞれを比較するとか、最長240個も比較するとなると、結構待たされることになるだろう。
何らかの使えそうなツールが出来たら、Owndのほうに上げておく。
ではでは