無料ブログはココログ

« [iPhone4] 音楽・ムービーをスリープ中に聴く・停める | トップページ | [HTML5] fillTextを使わずにCanvasに文字を出力してみる2 »

[HTML5] fillTextを使わずにCanvasに文字を出力してみる

HTML5の規格が策定中のためか、ブラウザのサポートもあまり進んでいないようです。Canvasに文字を出力するには、fillTextとstrokeTextがあるのですが、これをサポートしていなかったり(iPhone+iOS3、Android(バージョンによるかもしれません), IE+exCanvas)とか、線の太さを変えられないもの(IE+uuCanvas)があるようです。

とはいえ、図やグラフを出力すれば文字も出したいものです。せめて英数字だけでも出そうと試みました。まだまだ技術的な可能性を確認したレベルですし、そもそもJavaScriptを書くのも初めてなので、まだクラスにもできていなかったり、何度もロードしてやっとfirefoxで動く程度で、Safariが偶然一度だけ動いた状態です(たぶん、onloadを待つ必要があるのでしょう)。

とはいえ、データも作成しましたので、こうかいします。興味のある方は、自由に改造して使ってみてください。ご意見がいただけるとうれしいです。

Carageneout
(左がフォントの中間調を少し残したもの、右が2値にしたもの。クリックすると原寸で表示されます)

<考え方>

有識者に聞くと、divで文字を重ねる、イメージを貼る(遅ければまとめてcssスプライトを使う)などというアイデアをいただきましたが、管理対象が増える、ブラウザ毎の対応が大変、Webのスキルの低い私には壁が高い、という問題があります。そこで、思い出したのが日経ソフトウェアで紹介されていたCraftymind Articleのデモです。

このデモのソースを見ると、<div style="display:none".. としてビデオとCanvasを不可視の状態で置いておき、drawImageでビデオ->裏Canvas->表Canvasとコピーしているようです。2回もコピーして、あのような速度が出るなら文字表示も大丈夫だろうと考えたわけです。

昔のパソコンにはキャラクタージェネレータというハードウェアがあり、ROMにある文字のドットイメージを画面に表示するVRAMに転送していました。その方式はGUIになった今もフォントのイメージをレンダリングによって得ているものの、その後はビデオチップの機能でまとめて転送しているはずなので、今も基本的に変わらない仕組みだと思います。

このキャラクタジェネレータをソフトで実現しようと考えました。上に挙げたデモのように非表示のCanvasを使ってフォントのイメージをまとめて置いておき、表示したい文字をそこから表に転送するのです。

<フォントのイメージ>

さて、そこで気になるのがフォントのイメージをどう手に入れるかと言うことです。

かつてムンパッパなるハンドルで、FM-TOWNS用に縮小印字ソフトを公開したことがあります。このときは、印刷時にTOWNSのROMからフォントイメージを読んでそのマシンのプリンタに出力していました。所有者が同じであること、印刷時に取り出すだけで保存しないことから、私的利用の範囲であると気にしませんでした。しかい、今回は別のマシンで参照され、保存・配布もするので明らかな2次利用になのでライセンスが気になりました。

調べてみると、日本はタイプフェイスを保護する条約に入っていないようですが、MicroSoftなどのサイトによると、Windowsのフォントを利用できるのはWindowsだけのようです(フォントにもよります)。そこで、2次利用に問題のないフォントを探しました。ひとまず欧文256文字(ISO 8859-1)を考えていたこと、等幅フォントでないと配置がめんどくさい、見た目が良かった、ということで、M+ FONTS(アウトライン)を使いました。

手順的には、コードの一覧をつくり表示、キャプチャ、補正、透明化、としました。

1.コード一覧の作成
結構大変でした。Wikipediaの一覧を使おうとしましたが、Unicodeなのでフォントによって2バイトコードのフォントを使うものがあって表の幅がそろいませんでした。英語サイトの方がましでしたがWebで狭い幅にそろえるのは難しかったです。結局、英語のWikipedhiaの一覧からコードを拾ってExcelに貼りました(希望者が折られましたら、差し上げます)。

2.キャプチャ
キャプチャソフトは何でも良いですが、フォントをM+2mにして、ノイズがのらないようにbmpで保存しました。

3.補正
そのまま使うと中間調の部分が多いので、Paint.Netで少し減らしたものと2値のものを作成しました(上のイメージのように中間長の部分は透明にならないので)。また、等幅フォントはプログラミングを考慮してゼロの中央に点があるのですが、使いにくかったので消させていただきました。

4.透明化
shin's Palette PNG Editorで透明色を指定しました。

<開発>

プログラム自体はリンクを見ていただければ分かりますが、イメージの構成に自由度を持たせたことで計算式がややこしいぐらいで大したことはありません(JavaScriptをあまり知らないので時間がかかりましたが、、、)

<今後の野望>

いずれiOS4やIE9が普及すれば用なしになりますが、イメージのかたまりを渡しておいて好きなところに配置できるので、様々な場面で使えるかと思います。ゲームを作っても面白いかもしれません。

ということで、こんな野望を持っています。

・表示されない問題をなくして、fillTextの使えないブラウザにも対応する。
・クラス化してライブラリにする
・拡大縮小をサポートする
・設定ファイルを読むようにする
・フォントのイメージファイルをそろえる
   :
・擬似グラフィックでゲームを作る

どこまでやるかはわかりませんが、コメントをいただけるとうれしいです。

つづく

« [iPhone4] 音楽・ムービーをスリープ中に聴く・停める | トップページ | [HTML5] fillTextを使わずにCanvasに文字を出力してみる2 »

パソコン・インターネット」カテゴリの記事

ソフトウェア」カテゴリの記事

プログラミング」カテゴリの記事

コメント

非表示の Canvas を経由すると、フォントの画像を加工(擬似 Bold フォントの生成とか)できるというメリットはあると思いますが、そうでなければ、drawImage でフォントの画像ファイルから直接矩形領域を切り出して表示する方が、楽なのではないでしょうか?

参考になるか分かりませんが、こういうライブラリもあったりします。
http://code.google.com/p/canvas-text/

コメントありがとうございます。
言われてみればそうですね。直接drawImageする方が早いですし、管理も楽ですね。

canvas-textはすごいですね。思わず検討しましたが、フォントのサイズが2MByteもあるので、モバイル環境向けにはつらいですね。

職場の人からも助言をいただけたので別記事に更新する予定です。

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: [HTML5] fillTextを使わずにCanvasに文字を出力してみる:

« [iPhone4] 音楽・ムービーをスリープ中に聴く・停める | トップページ | [HTML5] fillTextを使わずにCanvasに文字を出力してみる2 »