Pyxel BDFRendererクラスの改造

<2023-04-30 追記>
本記事のコード改造内容は,Pyxel 1.9.14以降の公式サンプル 13_bitmap_font.py に反映されていますので,サンプルのコードをそのまま使用できます。

Pyxelでの日本語表示(ビットマップフォントの描画)

 Pyxelで日本語を含むビットマップフォントの描画についての記事Pyxel ビットマップフォントがずれる場合の対応 - 勉強ボックス管理者ブログで,サンプルのフォント以外のずれを修正する対応を紹介しましたが,draw_text()で指定するxy座標から離れてしまう問題がありました。
 フォント描画位置を見直しファイルを修正しましたので,下の修正後のファイルのコードを確認してください。

修正後のファイル

【ファイル】 bdfrenderer.py
【使い方】
 draw_text( x, y, str, [color], [border_color], [spacing] )
 x座標,y座標,文字列,文字色,縁取り色,文字間隔(int)

from bdfrenderer import BDFRenderer
bdf = BDFRenderer("umplus_j10r.bdf")
bdf.draw_text( 10, 10,  "日本語表示", 7 )

 【コード例のフォルダ】 game/pyxel/bmpfont at main · benkyoubox/game · GitHub

※縁取り時の文字間隔が狭まっているため,元の処理の表示に見た目を近づけるには,最後の引数で1を指定してください。

bdf1.draw_text(24, 8, "Pyxel♪", 8)
bdf2.draw_text(4, 98, "気軽に楽しく", 7, 5, 1) # spacing= 1
bdf2.draw_text(4, 113, "プログラミング!", 7, 5, 1) # spacing=1


※以下は参考まで

問題点と対策

 美咲フォントをPyxelアプリケーションで描画したときに以下の問題があった
 ・アルファベット小文字などの位置が上にずれる
 ・空白文字が反映されない

 <対策>
 ・bdfファイル内の FONTBOUNDINGBOX のパラメータを参照して上下位置を決める
 ・bdfファイル内の DWIDTH の値を,次の文字の描画開始位置にする

 【参考サイト】itouh の部屋 itouh: BDFについて と,続き bdf2bmp


 <上下位置検討>
・通常のフォントの表示は下図の黒枠「PBX w h offset_x offset_y」と赤枠「FONTBOUNDINGBOX w h offset_x offset_y」が原点が同じになるように重なる。
・BDFRendererでフォントの描画はPBXの左上からスタートするので,draw_text()で指定するxy座標から黒枠PBXの左上の座標を決めたい。
 基本は赤枠の高さから黒枠の高さを引けばよいので,(赤枠の高さ+オフセット)-(黒枠の高さ+オフセット)の値分 y座標をずらしたところが描画スタートになる。


他の文字のデータでも確認

動作確認

下記のテストプログラムの,画面サイズ,フォント名,sizeを変更して表示を確認した。
(一部rectb()で文字と同じ座標指定で矩形を描いて,期待する位置に描画されるかどうかを確かめています)

import pyxel
from bdfrenderer import BDFRenderer

pyxel.init(512, 512, capture_scale=2)

fontfile = "umplus_j10r.bdf"
size = 10
bdf = BDFRenderer(fontfile)

pyxel.cls(1)

data =[ "0123456789+-*/=\\ abcdefghijklmnopqrstuvwxyz",
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ'\"<>_",
        "あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、",
        "うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。",
        "―――宮沢賢治『ポラーノの広場』より―――"]

pyxel.text(10,2,fontfile,11)
y = 12
for i in range(len(data)):
    bdf.draw_text(10, y, data[i], 7 )
    y += size + 4

y += 8
for i in range(len(data)):
    pyxel.rectb(10, y, pyxel.width-20, size, 5)
    bdf.draw_text(10, y, data[i], 7 , spacing=1)
    y += size + 4

y += 8
for i in range(len(data)):
    bdf.draw_text(10, y, data[i], 7, 9 )
    y += size + 4

y += 8
for i in range(len(data)):
    pyxel.rectb(10, y, pyxel.width-20, size, 5)
    bdf.draw_text(10, y, data[i], 7, 9, 2)
    y += size + 4

pyxel.show()


・サンプルのフォント 10pt

・サンプルのフォント 12pt

8×8 ドット日本語フォント「美咲フォント」

8×12 ドット日本語フォント「k8x12」

・b16.bdf(Unicode Font from /efont/


・他の文字も確認



関連記事

kinutani.hateblo.jp