mieki256's diary



2024/02/13(火) [n年前の日記]

#1 [basic] FreeBASICでCustom fontを使ってみたい

FreeBASICは、Draw String() を使うと、グラフィックス画面にテキストを描画することができる。ただ、使われるフォントが豆粒みたいに小さくて読みづらい…。もう少し大きいフォントを使いたい。

一応、Draw String はカスタムフォントを利用できるらしいので、そのあたりを試してみた。

ファイル一式は以下。

_fbcustomfont_20240213.zip

カスタムフォントの仕様 :

bitmap font が敷き詰められたフォント画像(.bmp)を与えればすぐさま利用できるのかなと思ったけれど、どうやらそんな単純な仕様では無さそうで…。

_DrawString
_FBgfx Image and Font Buffers - FreeBASIC Wiki Manual | FBWiki

bitmap font画像を渡すまでは予想通りだったけど、そのbmp画像の中にフォント情報(対象文字コードや各文字の横幅)も含ませておかないといかんらしい。

まず、bmp画像の最初の1ラスター目が、font header になっていて、そこにフォント情報を byte 単位で書き込まないといけないらしい。実際の bitmap font部分は、2ラスター目から置かれている。

about_fbfont.png


font header の内容は以下。

about_fbfont_header.png

1 byte目 : Version情報。これは現在 0 しか用意されてないらしい。
2 byte目 : 開始文字コード。例えば ASCIIコードの「空白」から始まるなら、0x20になる。
3 byte目 : 終了文字コード。例えば ASCIIコードの「DEL」で終わるなら、0x7f になる。
4 byte目 : 開始文字 + 0 の横幅ドット数
5 byte目 : 開始文字 + 1 の横幅ドット数
6 byte目 : 開始文字 + 2 の横幅ドット数
...
...
N byte目 : 終了文字の横幅ドット数

個人的に、この仕様はどうなんだと思えた。例えば画像編集ソフトでフォント画像を開いて、色調補正をしただけで、フォント情報が一発で破壊されてしまう。よろしくない気がする。いやまあ、フォント画像一つでカスタムフォントを扱いたい、フォント画像の中にフォント情報まで含めてしまいたい、と考えたらこうなったのだろうとは想像できるけど…。

変換ツールを書いてみた :

とりあえず、使ってみよう…。

等幅フォント、色深度32bitに限定して、読み込んだ bitmapフォント画像(.bmp)に Font header情報を追加/書き込んでから、bmp画像として保存するツールを書いてみた。

例えば、以下のように、ASCIIコード 0x20 - 0x7f の文字が、横一列に並んでいるbitmapフォント画像を用意して…。

_fbfont_bs_pet2015_16x16.bmp


このbmp画像を読み込んで、Font header 情報を追加して、以下のようなカスタムフォント用画像として出力する。

_fbfont_pet2015_16x16.bmp

見た目で違いは分からないだろうけど、一番上に1ラスター分追加されていて、そこに Font header情報が書き込まれている。


変換ツールのソースは以下。

_make_mono_font.bas
Const START_CHR = &H20
Const END_CHR   = &H7f

Const SCRW = 800
Const SCRH = 600
Dim As Integer sdepth = 32

If Command(1) = "" And Command(2) = "" Then
    Print "Usage: " & Command(0) & " INPUT.bmp OUTPUT.bmp" : End
End If

Dim As String infilename  = Command(1)
Dim As String outfilename = Command(2)

Dim As Integer f
Dim As Long w, h

' open bitmap file
f = FreeFile()
Open infilename For Binary Access Read As #f
If Err > 0 Then Print "Error: Can not open file" : End

' get bitmap width and height
Get #f, 19, w    ' get width
Get #f,   , h    ' get height
Close #f

ScreenRes SCRW, SCRH, sdepth

' load base font image
Dim As Any Ptr base_font = ImageCreate(w, h, RGB(0, 0, 0))
bload infilename, base_font

Print "Load : " & infilename

' create new font image
Dim As Any Ptr out_font = ImageCreate(w, h + 1, RGB(255, 0, 255))
Put out_font, (0, 1), base_font, PSet

' get custom font header address
Dim As ubyte Ptr headerp
ImageInfo out_font, , , , , headerp

' set header
headerp[0] = 0
headerp[1] = START_CHR  ' first character code
headerp[2] = END_CHR    ' end character code

' get 1 character Width
Dim As Integer cw = Int(w / (END_CHR - START_CHR + 1))
For i As Integer = 0 To (END_CHR - START_CHR)
    headerp[3 + i] = cw
Next i

bsave outfilename, out_font

color RGB(255, 255, 255), RGB(0, 0, 0)
Print "Save : " & outfilename
Print "Push Any Key"
sleep

ImageDestroy out_font
ImageDestroy base_font

fbc make_mono_font.bas でコンパイル。

使い方は以下。
Usage: make_mono_font.exe INPUT_FONT.bmp OUTPUT_FONT.bmp

テスト表示してみる :

変換して生成されたフォント画像(.bmp)を読み込んで、カスタムフォントとして利用してみる。

_test_fbfont.bas
Const SCRW = 512
Const SCRH = 288
Dim As Integer sdepth = 32

If Command(1) = "" Then
    Print "Usage : " & Command(0) & " INPUT_FONT.bmp" : end
End If

ScreenRes SCRW, SCRH, sdepth

Dim As String infilename  = Command(1)

Dim As Integer f
Dim As Long w, h

' open bitmap file
f = FreeFile()
Open infilename For Binary Access Read As #f
If Err > 0 Then Print "Error: Can not open file" : End

' get bitmap width and height
Get #f, 19, w    ' get width
Get #f,   , h    ' get height
Close #f

Dim As Any Ptr img = ImageCreate(w, h)
bload infilename, img

Color RGB(255, 255, 255), RGB(0, 0, 0)
cls

h = 34
Draw String (0, h * 0), "Hello World !", , img
Draw String (0, h * 1), infilename, , img
Draw String (0, h * 2), "0123456789",    , img
Draw String (0, h * 3), "@ABCDEFGHIJKLMNO", , img
Draw String (0, h * 4), "PQRSTUVWXYZ[\]^_", , img
Draw String (0, h * 5), "`abcdefghijklmno", , img
Draw String (0, h * 6), "pqrstuvwxyz{|}~ ", , img

sleep
ImageDestroy img

fbc test_fbfont.bas でコンパイル。

使い方は以下。表示してみたいフォント画像をコマンドラインオプションで指定する。
Usage: test_fbfont.exe INPUT_FONT.bmp

ss_fbfont_pet2015_16x16.png

たしかに、カスタムフォントが利用できた。

再度メモ。ファイル一式は以下。

_fbcustomfont_20240213.zip

他のフォントを利用した際のスクリーンショット :

以前、 _OpenGLでビットマップフォントを描画した際 のフォントデータを利用して試してみた。

courR18 (16x26)

ss_fbfont_courR18_16x26.png


profont (12x22)

ss_fbfont_profont_12x22.png


東雲フォント shnm8x16r (8x16)

ss_fbfont_shnm8x16r_8x16.png


東雲フォント2倍拡大 shnm8x16r x 2 (16x32)
ss_fbfont_shnm8x16rx2_16x32.png


Terminus font (12x24)

ss_fbfont_ter-u24b_12x24.png


各フォントの入手先やライセンスは以下を参照のこと。

_readme.md

以上です。

過去ログ表示

Prev - 2024/02 - Next
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project