2024/01/13(土) [n年前の日記]
#1 [prog] OpenGL + glBitmapで文字描画をしたい
OpenGL で文字描画をしたい。
_昨日の実験
で、wglUseFontBitmaps() を使えば文字描画ができることは分かったけれど、Windowsに特化しているあたりがなんだかちょっと微妙になんとなく気になる。ここは一つ、Linux あたりでも使えそうな方法でやれないものか。
そんなわけで、2値画像を描画できるという glBitmap() を使えば、Windows以外でも使えるのではないかと思えてきたので、そのあたりを試してみた。
そんなわけで、2値画像を描画できるという glBitmap() を使えば、Windows以外でも使えるのではないかと思えてきたので、そのあたりを試してみた。
◎ glBitmapで画像を描画 :
まずは glBitmap() の基本的な使い方を把握したい。以下のページが参考になった。ありがたや。
_ビットマップ
その前に、画像をビットパターンの配列に変換するツールが欲しいなと…。png画像を読み込んで、unsigned char の配列にして出力する Pythonスクリプトを書いてみた。環境は、Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0。
_png2bits.py
使い方は以下。
やってることは、PIL(Pillow)でpng画像を読み込んでグレースケール画像に変換して、各ドットをチェックして値が128より大きければ1に、小さければ0にして、8ドット=1byteにまとめて並べて出力しているだけ。OpenGLは下から上に画像を描画していくらしいので、png画像をスキャンしていくときも下から上に見ていくようにした。
このスクリプトを使って、以下の画像を C言語の .h の形に変換。
_image_32x32.png
_image_lena.png
以下のような .h が得られた。
_image_32x32.h
_image_lena.h
内容は以下のような感じ。
これで描画すべきビットパターンの配列は得られた。OpenGL の glBitmap() で描画するプログラムを書いてみる。
ビルドは、Windows10 x64 22H2上で、MinGW (gcc 6.3.0) / MSYS2 MINGW64 (gcc 13.2.0) + freeglut を使った。
_01_glbitmap.c
_Makefile
make と打って、01_glbitmap.exe が生成された。実行結果は以下。
両方とも描画できた。
_ビットマップ
その前に、画像をビットパターンの配列に変換するツールが欲しいなと…。png画像を読み込んで、unsigned char の配列にして出力する Pythonスクリプトを書いてみた。環境は、Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0。
_png2bits.py
""" png image to c header file Usage: python png2bits.py -i input.png --label label_name > image.h Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0 """ import argparse import os import sys from PIL import Image def main(): parser = argparse.ArgumentParser() parser.add_argument("-i", "--infile", required=True, help="PNG image file") parser.add_argument("--label", help="symbol name") args = parser.parse_args() infile = args.infile if os.path.isfile(infile): print("/* infile: %s */" % infile) else: print("Error: Not found %s" % infile) sys.exit() if not args.label: label = infile.replace(".", "_") label = label.replace(" ", "_") else: label = args.label im = Image.open(infile).convert("L") im.point(lambda x: 0 if x < 128 else x) w, h = im.size print("static unsigned int %s_width = %d;" % (label, w)) print("static unsigned int %s_height = %d;\n" % (label, h)) print("static unsigned char %s[] = {" % (label)) count = 0 for y in range(h - 1, -1, -1): buf = [] for i in range(int(w / 8)): buf.append(0) if (w % 8) != 0: buf.append(0) for x in range(w): v = im.getpixel((x, y)) if v > 128: buf[int(x / 8)] |= 1 << (7 - (x % 8)) s = "" for v in buf: s += "0x%s," % format(v, "02x") count += 1 print(" %s // %d" % (s, y)) print("};\n") print("static unsigned int %s_len = %d;" % (label, count)) if __name__ == "__main__": main()
使い方は以下。
python png2bits.py -i INPUT.png --label LABEL_NAME > OUTPUT.h
やってることは、PIL(Pillow)でpng画像を読み込んでグレースケール画像に変換して、各ドットをチェックして値が128より大きければ1に、小さければ0にして、8ドット=1byteにまとめて並べて出力しているだけ。OpenGLは下から上に画像を描画していくらしいので、png画像をスキャンしていくときも下から上に見ていくようにした。
このスクリプトを使って、以下の画像を C言語の .h の形に変換。
以下のような .h が得られた。
_image_32x32.h
_image_lena.h
内容は以下のような感じ。
/* infile: image_32x32.png */ static unsigned int image_32x32_width = 32; static unsigned int image_32x32_height = 32; static unsigned char image_32x32[] = { 0xff,0xff,0x00,0x00, // 31 0xff,0xff,0x00,0x00, // 30 // ... 0x01,0x80,0x55,0xcc, // 1 0x00,0x00,0xaa,0xcc, // 0 };
これで描画すべきビットパターンの配列は得られた。OpenGL の glBitmap() で描画するプログラムを書いてみる。
ビルドは、Windows10 x64 22H2上で、MinGW (gcc 6.3.0) / MSYS2 MINGW64 (gcc 13.2.0) + freeglut を使った。
_01_glbitmap.c
// draw bitmap sample on OpenGL #include <windows.h> #include <stdio.h> #include <GL/gl.h> #include <GL/freeglut.h> // include bitmap pattern #include "image_32x32.h" #include "image_lena.h" void display(void) { GLfloat xorig, yorig, xmove, ymove; GLsizei w, h; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // draw arrow glColor4f(1, 1, 1, 1); // set color glRasterPos2f(-0.5, -0.5); // set position xorig = 0.0; yorig = 0.0; xmove = 0.0; ymove = 0.0; w = image_32x32_width; h = image_32x32_height; glBitmap(w, h, xorig, yorig, xmove, ymove, image_32x32); // draw bitmap // draw lena glColor4f(1.0, 0.8, 0.5, 1); glRasterPos2f(0.0, 0.0); xorig = 0.0; yorig = 0.0; xmove = 0.0; ymove = 0.0; w = image_lena_width; h = image_lena_height; glBitmap(w, h, xorig, yorig, xmove, ymove, image_lena); glFlush(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case '\x1B': case 'q': // Exit on escape or 'q' key press glutLeaveMainLoop(); // exit(EXIT_SUCCESS); break; } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(512, 288); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH); glutCreateWindow("glBitmap sample"); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutMainLoop(); return EXIT_SUCCESS; }
_Makefile
PROGRAM = 01_glbitmap.exe SRC = $(PROGRAM:%.exe=%.c) ifeq ($(MSYSTEM),MINGW64) # -------------------- # MSYS2 MINGW64 $(PROGRAM): $(SRC) image_32x32.h image_lena.h Makefile gcc $< -o $@ -lglu32 -D FREEGLUT_STATIC -lfreeglut -lopengl32 -lwinmm -lgdi32 -static else # -------------------- # MinGW $(PROGRAM): $(SRC) image_32x32.h image_lena.h Makefile gcc $< -o $@ -lglu32 -D FREEGLUT_STATIC -lfreeglut_static -lopengl32 -lwinmm -lgdi32 endif image_32x32.h: image_32x32.png Makefile python png2bits.py -i $< --label image_32x32 > $@ image_lena.h: image_lena.png Makefile python png2bits.py -i $< --label image_lena > $@ .PHONY: clean clean: rm -f *.exe rm -f *.o rm -f image_32x32.h rm -f image_lena.h
make と打って、01_glbitmap.exe が生成された。実行結果は以下。
両方とも描画できた。
◎ glBitmapで文字描画をしてみる :
glBitmap() を使えば2値画像を描画できることが分かったので、コレを使って文字描画ができないか試してみる。ひとまず、英数字のみを等幅フォントで描画する方向で考える。
その前に、フォントデータを作らないといけない…。コレも、Python を使って、フォントを敷き詰めた画像からビットパターンを作って、unsigned char 配列として出力するスクリプトを書いてみた。環境は、Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0。
_fontpng2bits.py
使い方は以下。
フォント画像は以下のものを用意した。ASCIIコード 0x20 - 0x7f までを、横16文字、縦6行に、等幅で敷き詰めた画像を用意する。各フォントの入手先については後述する。
_font_pet2015.png
_font_courR18.png
_font_shnm8x16r.png
_font_shnm8x16rx2.png
_font_profont.png
_font_ter-u24b.png
これを先ほどのPythonスクリプトに渡して、C言語の .h(ヘッダーファイル)の形にした。
_fontdata.h
_fontdata_courr18.h
_fontdata_shnm8x16r.h
_fontdata_shnm8x16rx2.h
_fontdata_profont.h
_fontdata_ter-u24b.h
中身は以下のような感じになっている。文字1つ毎に配列になってる、2次元配列として用意した。
フォントデータが用意できたので、glBitmap() で描画してみる。ソースは以下。文字描画の処理をしているのは、drawText() の部分。
環境は、Windows10 x64 22H2 + MinGW (gcc 6.3.0) / MSYS2 MINGW64 (gcc 13.2.0) + freeglut。
_02_drawbitmapfont.c
最初、表示がグチャグチャになってハマってしまった。glPixelStorei(GL_UNPACK_ALIGNMENT, 1); を入れないと思った通りに描画されなかった。
_Makefile
Makefile には、先ほど用意した全フォントデータ(.h) を生成する行も記述しちゃってるけど、不要なら該当行は消してしまって構わない。
make でビルド。得られた 02_drawbitmapfont.exe を実行すると以下のような結果になった。
文字(文字列)を描画することができた。
ソースの最初のほうのコメントアウトを修正して、別のフォントを描画してみると、以下のような感じになる。印象が結構違うなと…。
courR18.bdf の例。
東雲フォント(shnm8x16r.bdf)の例。
東雲フォント(shnm8x16r.bdf)を2倍に拡大した例。
ProFontの例。
Terminus Font の例。
ということで、glBitmap() を使って、OpenGL で文字描画をすることができる、と分かった。
余談。これらのフォントデータと、glBitmap() を使って描画する関数を、一つの .h(ヘッダーファイル)にまとめてしまって、「この .h を1つ #include すれば文字描画できますよ」という形にしてしまえば少しは便利に使えるかもしれないなと…。
もっとも…。
その前に、フォントデータを作らないといけない…。コレも、Python を使って、フォントを敷き詰めた画像からビットパターンを作って、unsigned char 配列として出力するスクリプトを書いてみた。環境は、Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0。
_fontpng2bits.py
""" font png image to c header file Usage: python fontpng2bits.py -i input.png --label label_name > image.h Windows10 x64 22H2 + Python 3.10.10 64bit + Pillow 10.1.0 """ import argparse import os import sys from PIL import Image def main(): parser = argparse.ArgumentParser() parser.add_argument("-i", "--infile", required=True, help="PNG image file") parser.add_argument("--label", help="symbol name") args = parser.parse_args() infile = args.infile if os.path.isfile(infile): print("/* infile: %s */" % infile) else: print("Error: Not found %s" % infile) sys.exit() if not args.label: label = infile.replace(".", "_") label = label.replace(" ", "_") else: label = args.label im = Image.open(infile).convert("L") im.point(lambda x: 0 if x < 128 else x) imgw, imgh = im.size w = int(imgw / 16) h = int(imgh / 6) print("/* source image size = %d x %d */\n" % (imgw, imgh)) print("static int %s_width = %d;" % (label, w)) print("static int %s_height = %d;" % (label, h)) alen = int(w / 8) + (1 if (w % 8) != 0 else 0) clen = alen * h cnum = 16 * 6 print("static int %s_chr_len = %d;\n" % (label, clen)) print("static unsigned char %s[%d][%d] = {" % (label, cnum, clen)) for c in range(16 * 6): bx = int(c % 16) * w by = int(c / 16) * h print(" {") print(" // code = 0x%02x" % (c + 0x20)) for y in range(h - 1, -1, -1): buf = [] for i in range(alen): buf.append(0) for x in range(w): v = im.getpixel((bx + x, by + y)) if v > 128: buf[int(x / 8)] |= 1 << (7 - (x % 8)) s = "" for v in buf: s += "0x%s," % format(v, "02x") print(" %s" % s) print(" },") print("};") if __name__ == "__main__": main()
使い方は以下。
python fontpng2bits.py -i INPUT.png --label LABEL_NAME > OUTPUT.h
フォント画像は以下のものを用意した。ASCIIコード 0x20 - 0x7f までを、横16文字、縦6行に、等幅で敷き詰めた画像を用意する。各フォントの入手先については後述する。
これを先ほどのPythonスクリプトに渡して、C言語の .h(ヘッダーファイル)の形にした。
_fontdata.h
_fontdata_courr18.h
_fontdata_shnm8x16r.h
_fontdata_shnm8x16rx2.h
_fontdata_profont.h
_fontdata_ter-u24b.h
中身は以下のような感じになっている。文字1つ毎に配列になってる、2次元配列として用意した。
/* infile: font_pet2015.png */ /* source image size = 256 x 96 */ static int fontdata_width = 16; static int fontdata_height = 16; static int fontdata_chr_len = 32; static unsigned char fontdata[96][32] = { { // code = 0x20 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00, // ... 0x00,0x00, 0x00,0x00, }, { // code = 0x21 0x00,0x00, // ... 0x0c,0x30, 0x03,0xc0, 0x03,0xc0, }, };
フォントデータが用意できたので、glBitmap() で描画してみる。ソースは以下。文字描画の処理をしているのは、drawText() の部分。
環境は、Windows10 x64 22H2 + MinGW (gcc 6.3.0) / MSYS2 MINGW64 (gcc 13.2.0) + freeglut。
_02_drawbitmapfont.c
// bitmap font draw sample on OpenGL #include <windows.h> #include <stdio.h> #include <string.h> #include <GL/gl.h> #include <GL/freeglut.h> // include bitmap pattern // -------------------- // #include "fontdata.h" // #include "fontdata_courr18.h" // #include "fontdata_shnm8x16r.h" // #include "fontdata_shnm8x16rx2.h" // #include "fontdata_profont.h" #include "fontdata_ter-u24b.h" #define SCRW 512 #define SCRH 288 static int framerate = 60; static int count = 0; // draw text void drawText(char *str) { GLsizei w = (GLsizei)fontdata_width; GLsizei h = (GLsizei)fontdata_height; int clen = fontdata_chr_len; GLfloat xorig, yorig; GLfloat xmove, ymove; xorig = 0; yorig = 0; xmove = w; ymove = 0; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // コレが無いと表示が崩れる int slen = strlen(str); for (int i = 0; i < slen; i++) { int c = str[i]; if (c == 0) break; if (c < 0x20 || c > 0x7f) c = 0x20; c -= 0x20; glBitmap(w, h, xorig, yorig, xmove, ymove, &(fontdata[c][0])); } } // draw OpenGL void display(void) { GLfloat xorig, yorig, xmove, ymove; GLsizei w, h; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); // draw text glColor4f(1, 1, 1, 1); // set color glRasterPos2f(-0.8, 0.5); // set position drawText("Hello World !!"); { char buf[256]; sprintf(buf, "count %d", count); glRasterPos2f(-0.8, 0.0); drawText(buf); } glutSwapBuffers(); glFlush(); count++; } void onTimer(int value) { glutPostRedisplay(); // redraw glutTimerFunc((1000 / framerate), onTimer, 0); } void keyboard(unsigned char key, int x, int y) { switch (key) { case '\x1B': case 'q': // Exit on escape or 'q' key press glutLeaveMainLoop(); // exit(EXIT_SUCCESS); break; } } int main(int argc, char **argv) { count = 0; glutInit(&argc, argv); glutInitWindowSize(SCRW, SCRH); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutCreateWindow("bitmap font draw sample"); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glutTimerFunc((1000 / framerate), onTimer, 0); glutMainLoop(); return EXIT_SUCCESS; }
最初、表示がグチャグチャになってハマってしまった。glPixelStorei(GL_UNPACK_ALIGNMENT, 1); を入れないと思った通りに描画されなかった。
_Makefile
PROGRAM = 02_drawbitmapfont.exe SRC = $(PROGRAM:%.exe=%.c) FONTS = fontdata.h fontdata_courr18.h fontdata_shnm8x16r.h fontdata_shnm8x16rx2.h fontdata_profont.h fontdata_ter-u24b.h ifeq ($(MSYSTEM),MINGW64) # -------------------- # MSYS2 MINGW64 $(PROGRAM): $(SRC) $(FONTS) Makefile gcc $< -o $@ -lglu32 -D FREEGLUT_STATIC -lfreeglut -lopengl32 -lwinmm -lgdi32 -static else # -------------------- # MinGW $(PROGRAM): $(SRC) $(FONTS) Makefile gcc $< -o $@ -lglu32 -D FREEGLUT_STATIC -lfreeglut_static -lopengl32 -lwinmm -lgdi32 endif fontdata.h: font_pet2015.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ fontdata_courr18.h: font_courR18.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ fontdata_shnm8x16r.h: font_shnm8x16r.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ fontdata_shnm8x16rx2.h: font_shnm8x16rx2.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ fontdata_profont.h: font_profont.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ fontdata_ter-u24b.h: font_ter-u24b.png fontpng2bits.py Makefile python fontpng2bits.py -i $< --label fontdata > $@ .PHONY: clean clean: rm -f *.exe rm -f *.o rm -f fontdata.h
Makefile には、先ほど用意した全フォントデータ(.h) を生成する行も記述しちゃってるけど、不要なら該当行は消してしまって構わない。
make でビルド。得られた 02_drawbitmapfont.exe を実行すると以下のような結果になった。
文字(文字列)を描画することができた。
ソースの最初のほうのコメントアウトを修正して、別のフォントを描画してみると、以下のような感じになる。印象が結構違うなと…。
courR18.bdf の例。
東雲フォント(shnm8x16r.bdf)の例。
東雲フォント(shnm8x16r.bdf)を2倍に拡大した例。
ProFontの例。
Terminus Font の例。
ということで、glBitmap() を使って、OpenGL で文字描画をすることができる、と分かった。
余談。これらのフォントデータと、glBitmap() を使って描画する関数を、一つの .h(ヘッダーファイル)にまとめてしまって、「この .h を1つ #include すれば文字描画できますよ」という形にしてしまえば少しは便利に使えるかもしれないなと…。
もっとも…。
- glut を使っていたら、既に文字描画できる関数 glutBitmapCharacter() があったりするし。
- Windowsに特化すれば wglUseFontBitmaps() があるし。
- Linux なら FTGLライブラリがあるし。
◎ フォントの入手先 :
前述のように、ASCIIコード 0x20 - 0x7f を、横16文字 x 縦6行で、等幅で並べた画像さえあれば、こうしてフォントデータを用意できるので、元になるフォントは画像でもbdfフォントでもなんでも使えるはず。要は、以下の文字さえ用意してあればいい。
とりあえず、今回用意したフォント画像の元フォントの入手先をメモしておく。
一番最初に使った pet2015 というフォントは、自分が作ったビットマップフォント。ライセンスは CC0 / Public Domain。画像しか存在していない。1文字8x8ドット。8bit PC MZ-700のフォントに似せつつドット単位では別物になるようにドットを打った。 *1
_mieki256's diary - HGIMG3とビットマップフォント画像の作り方を勉強中
courR18.bdf は、ググったら Apple のサイトにあったのでそこから入手。bdfファイルの最初のほうにライセンスその他が書いてあると思うのだけど、英語分からん…。実験用なら使ってもいいのではないかと安易に思って使ってみたけど、実際はどうなんだろう…。
_courR18.bdf
東雲フォントは以下から入手。ライセンスは Public Domain。shinonome-0.9.11p1.tar.bz2 を入手して解凍。bdfフォルダの中に .bdfフォントが入っている。英数字部分は、6x12, 7x14, 8x16, 9x18 が用意されてる。
_shinonome font family
ProFont は以下から入手。ライセンスは _MIT License になっているらしい。profont-x11.zip を入手して解凍。pcfフォントしか入ってない。*.pcf を任意のフォルダに置いて、GIMP 2.8.22 Portable のフォントフォルダとして追加して、GIMP上で画像化してみた。 *2
_ProFont for Windows, for Macintosh, for Linux
Terminus Font は以下から入手。ライセンスは SIL Open Font License, Version 1.1。terminus-font-4.49.1.tar.gz を入手して解凍。bdfフォントが入っている。
_Terminus Font Home Page
!"#$%&'()*+,-./ 0123456789:;<=>? @ABCDEFGHIJKLMNO PQRSTUVWXYZ[\]^_ `abcdefghijklmno pqrstuvwxyz{|}~
とりあえず、今回用意したフォント画像の元フォントの入手先をメモしておく。
一番最初に使った pet2015 というフォントは、自分が作ったビットマップフォント。ライセンスは CC0 / Public Domain。画像しか存在していない。1文字8x8ドット。8bit PC MZ-700のフォントに似せつつドット単位では別物になるようにドットを打った。 *1
_mieki256's diary - HGIMG3とビットマップフォント画像の作り方を勉強中
courR18.bdf は、ググったら Apple のサイトにあったのでそこから入手。bdfファイルの最初のほうにライセンスその他が書いてあると思うのだけど、英語分からん…。実験用なら使ってもいいのではないかと安易に思って使ってみたけど、実際はどうなんだろう…。
_courR18.bdf
東雲フォントは以下から入手。ライセンスは Public Domain。shinonome-0.9.11p1.tar.bz2 を入手して解凍。bdfフォルダの中に .bdfフォントが入っている。英数字部分は、6x12, 7x14, 8x16, 9x18 が用意されてる。
_shinonome font family
ProFont は以下から入手。ライセンスは _MIT License になっているらしい。profont-x11.zip を入手して解凍。pcfフォントしか入ってない。*.pcf を任意のフォルダに置いて、GIMP 2.8.22 Portable のフォントフォルダとして追加して、GIMP上で画像化してみた。 *2
_ProFont for Windows, for Macintosh, for Linux
Terminus Font は以下から入手。ライセンスは SIL Open Font License, Version 1.1。terminus-font-4.49.1.tar.gz を入手して解凍。bdfフォントが入っている。
_Terminus Font Home Page
◎ bdfフォントの画像化 :
bdfフォントを画像化したい時は、bdf2bmp というツールが使える。
_bdf2bmp
使い方は以下。
デフォルトだと境界線(?)が入るけれど、オプションをつければ、境界線を入れない状態で出力できたり、横に並ぶ文字の個数を指定できたりする。以下は、境界線無し(0ドット幅)、横に16文字並べる指定。
こうして画像化してしまえば、任意のグリッドサイズを指定、かつ、グリッド単位で選択や移動ができる画像編集ソフトを使うことで、文字の並び替えもできるかなと。自分の場合は _ドットエディタ EDGE2 (シェアウェア) で作業してしまうことが多いけれど、GIMP のグリッド表示と吸着を有効化して作業できなくもないかなと…。
_bdf2bmp
使い方は以下。
bdf2bmp input.bdf output.bmp
デフォルトだと境界線(?)が入るけれど、オプションをつければ、境界線を入れない状態で出力できたり、横に並ぶ文字の個数を指定できたりする。以下は、境界線無し(0ドット幅)、横に16文字並べる指定。
bdf2bmp input.bdf output.bmp -s0 -c16
こうして画像化してしまえば、任意のグリッドサイズを指定、かつ、グリッド単位で選択や移動ができる画像編集ソフトを使うことで、文字の並び替えもできるかなと。自分の場合は _ドットエディタ EDGE2 (シェアウェア) で作業してしまうことが多いけれど、GIMP のグリッド表示と吸着を有効化して作業できなくもないかなと…。
*1: 余談。MZシリーズのフォントは PET 2001 というPCのフォントとクリソツで…。当時はなんというか、大らかだったんだなと…。
*2: _最近のバージョンのGIMPは一部のビットマップフォントが使えない という話があったので、今回、念のために、あえて GIMP 2.8.22 Portable を使って作業した。
*2: _最近のバージョンのGIMPは一部のビットマップフォントが使えない という話があったので、今回、念のために、あえて GIMP 2.8.22 Portable を使って作業した。
[ ツッコむ ]
以上、1 日分です。