Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

webにIVSの異体字を表示するには

$
0
0

前記事からの続きです。

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のほうに上げておく。


ではでは


Viewing all articles
Browse latest Browse all 5376

Trending Articles