21) 危険な香りがしたものの… 〜大量の画像2〜
Arjan Brugman(以下、Arjan)さんの『Use Japanese font in app』という質問がNS Basic社公式掲示板に投稿されました。
要するに、ローマ字とカナの表示を相互に変換表示できるモノを作りたいという事です。
そのために、画面に日本語を表示したいということですが、私の「J-OSがあるよ」という回答に、「NS Basic単体でやってみたい」という事でした。
内容などでは、カナだけでよい、という事なので、お節介がてら、ちょっとサンプルなど作ってみることにしました。

まず、ArjanさんのPalmは(当然ながら)英語版なので、カナのフォントを持っていません。
そこで、とりあえず、最低限度認識できる見えるレベルのカナフォントを作ってみました。
1文字が後ろの空白を含めて、6x6ピクセルという、スモールフォント並のフォントです。
一方、小さい「ヤユヨ」などは、5x6ピクセルに、濁点などの記号は4x6ピクセルで作ってみました。

   

   

   

これらのフォント、作成時間は大体30分くらいでしたが、ちょっと小さすぎですね(笑)
そして、続いて、サンプルアプリの作成に取りかかります。まずは、ローマ字→カナの変換を目指すことにしました。

ポイントは、画像ファイルの問題です。
フォントを1文字ずつ分解して各々を1つの画像するという作業は、正直い言うと、かなり面倒です。
そこで思いついたのが、このNS Basicについての第14回で取り上げた「大量の画像」というお話です。
その回では、あまり詳細を説明はしてありませんが、この仕組み自体、どうやら使えそうだという感触がありました。そこで、今回は、この方法に頼ることにしました。

この方法、あまり使われないCreateWindowというコマンドを使った方法なのですが、これは、次のような書式で描画エリアを作成します。

    CreateWindwo(名前, 横位置, 縦位置, 幅, 高さ)

例えば、画面の真ん中辺りに「SubArea」という名前のエリアを作る場合は、

    CreateWindow("SubArea",60,60,40,40)

とします。
イメージ的には、こんな具合でしょうか。

   


そして、そのエリアを描画対象を指定するには、SetCurrentWindowコマンドを使います。

    SetCurrentWindow "SubArea"

これで、エリアSubAreaの位置が仮想的なスクリーンとして描画対象になります。
重要な事は、このエリアは、1つの独立したエリアですので、SubAreaの左上の座標が(0,0)になるという事です。
第14回では、このエリアと座標を使って、大きな画像の小さな1部分を表示するという例を示しました。
この方法と同様に、今回用意したカナの画像の1文字分(6x6ピクセル)のエリアを作成して、その中に表示するという方法を使えば表示はできそうです。
例えば「サ」と表示しようとすれば、
	CreateWindow("SubArea",30,30,6,6)
	SetCurrentWindow "SubArea"
	DrawBitmap 1004,-60,0
とします。DrawBitmapの「-60」が1つのミソで、これを模式的に表すと、こんなイメージになります。

   

   

ここまでできれば、後は、、この場合の-60に相当するようなローマ字に対応した座標を得るだけですね。

さて1つ心配する点、これは第14回でも触れていますが、それは、CreateWindowで作成したエリアを、どうも個別に認識していないと思われる点です。
例えば、同じ名前のエリアを作成してもエラーにもなりません。
この場合は、後で作った方のエリアが有効になる、という事がわかっていますが、このことは、それ以前に作成したエリアにアクセスする手段がなくなってしまうことを表しています。
そのくせ、エリアを無効にすると、全部消えてしまいますので厄介です。

しかし「同名で新しいエリアを作成すると、以前のエリアにアクセスできなくなる」ということは、裏を返せば、その時点でプログラム的に捨てられていると楽観的に考えることにしました。
それなら、新しいエリアを次々に作っても問題はなさそう・・・と想像できます。

もう1つ注意するのは、エリア以外の部分の管理です。
描画対象を、あるエリアに作成した場合、実は、ラベルやフィールドなどの更新もそのエリア内を対象として行われる事があるようです。つまり、そのエリアの左上の仮想的な座標(0,0)をPalmのスクリーンの座標として捉えてしまう訳ですね。
そこで、スクリーン全体のエリアを定義しておき、必要な時だけカナ描画エリアを作成し、終わったら全体エリアに戻す、という方法を取ることにしました。

   

無責任ですが、ダメだったらランタイムが『致命的なエラー』の肩代わりをしてくれるでしょうから、ここはそれを信じて進みましょう。

さて、変換プログラムの中身は、今回のテーマから離れますので、実際のソースを見て下さい。
とりあえず、プログラムの形として、メインとなる描画部分は全部サブルーチン化しました。
あまり長い文字列を想定していないので、改行なし、という仕様です。
サブルーチンの戻り値は、実際に表示したピクセル数としましたので、やろうと思えば長文にも対応できるかもしれません。
まぁ、フォント作成と合わせて1時間くらいで作っちゃったインスタントプログラムなので、内容自体、洗練されてはいませんが・・・
ただ、考え方が日本人なので、「ガギグゲゴ」などの濁音や「パピプペポ」などの半濁音は、真面目に濁点、半濁点の記号を作って変換しています。どちらかと言えば、もう少し大きなフォントを用意して「ガ」とか「パ」とかを1文字にすべきだったですね(笑)
また、サンプルではカンマやピリオドを「、」「。」の句読点に変換します。またハイフンとスペースもとりあえず表示可能です。

実際、自分で遊んでみると、なんだか翻訳機を使って翻訳しているようで、ちょっと楽しいです。

   

まだ一部、ローマ字表記で対応していない部分もありますので、とんでもなく面白い変換をしてくれる場合があります。
「pinkuredyi-」は「ピンクレヂィー」ですから(笑)
(作成したサンプルプログラムは、ここからダウンロードできますので、よろしければ、お試しください。)

ちょっとした掲示板の書き込みで、このようなサンプルが返ってくるとは、驚いたでしょうかね?
日本人は親切かお人好しと思われているかもしれません。
でも、危険なテクニックで1時間くらいで作っちゃっていますから、なんとも言えませんが(笑)
幸いな事に、このサンプルには感謝されたので、この件は良しとしましょう。
ちなみに、ここで作成したのはローマ字→カナですが、Arjanさんはその逆も欲していました。
英語版OSという日本語フォントを持っていないところで、50文字以上のカナ文字からどうやってカナを選択・入力するか心配になりましたので、こちらは、日本語版OSなどについている「ソフトキーボード」の方式を紹介しておいた事を追記して、今回は終わりにしましょう。