--- nono/wx/wxtextpanel.cpp 2026/04/29 17:04:53 1.1.1.5 +++ nono/wx/wxtextpanel.cpp 2026/04/29 17:04:56 1.1.1.6 @@ -9,6 +9,7 @@ #include "bitrev.h" #include "cgrom.h" #include "kaname12.h" +#include "privatechar.h" #include "sjis.h" // @@ -22,6 +23,7 @@ static const wxSize fontinfo[] = { }; static_assert(countof(fontinfo) == FontId::Max, ""); + // コンストラクタ (style 指定なし) // (wxPanel の style のデフォルトは wxTAB_TRAVERSAL) WXTextPanel::WXTextPanel(wxWindow *parent) @@ -94,14 +96,46 @@ WXTextPanel::AllocFont(FontId fontid) int bytes = font_stride * font_height; std::vector buf(bytes); + // 半角文字領域 256 文字全部をキャッシュする。 + // ASCII は 0x7f までだが X680x0 の CGROM の 0x80, 0x81, 0x82 には + // '\\', '~', '|' が収納されている。 + // 制御文字領域を外字として使う。 wxBitmap **ascii_glyph = ascii_glyph_table[fontid]; wxBitmap **bold_glyph = bold_glyph_table[fontid]; - // 半角文字領域 256 文字全部をキャッシュする。ASCII は 0x7f までだが - // X680x0 の CGROM の 0x80, 0x81, 0x82 には '\\', '~', '|' が - // 収納されている。 - // また CGROM に収録されている半角ひらがなは使わないが、避けるのも - // 手間なのでここまで含めてデータを作っておく。 + + // 先に指定されたところに外字を割り当てる + for (int i = 0; private_chars[i].code != 0; i++) { + const auto& pchar = private_chars[i]; + const char *ptr; + + switch (fontid) { + case FontId::_6x12: + ptr = (const char *)pchar.xbm12; + break; + case FontId::_8x16: + ptr = (const char *)pchar.xbm16; + break; + default: + __unreachable(); + } + + // 元データはすでに XBM 形式。 + // ボールドにはしないので同じデータを入れておく。 + int ch = pchar.code; + assert(ascii_glyph[ch] == NULL); + assert(bold_glyph[ch] == NULL); + ascii_glyph[ch] = new wxBitmap(ptr, font_width, font_height, 1); + bold_glyph[ch] = new wxBitmap(ptr, font_width, font_height, 1); + } + + // CGROM に収録されている文字のうち半角ひらがななど使わないものもあるが + // 避けるのも手間なので気にせずデータを作っておく。 for (int ch = 0; ch < countof(ascii_glyph_table[0]); ch++) { + // すでに外字が設定されているところは避ける + if (ascii_glyph[ch]) { + continue; + } + const uint8 *ptr = base + ch * bytes; // wxBitmap は XBM 形式で 1bpp ビットマップを受け取る。 @@ -241,11 +275,6 @@ WXTextPanel::DrawChar2(wxDC& dc, int px, void WXTextPanel::DrawBitmap(wxDC& dc, int px, int py, const wxBitmap& bitmap) { - // 文字の背景は透過ではなく背景色で塗りつぶす - // (そうしないと元あった文字の上に重なってしまう) - // XXX dc につき最初の1回だけでいいのだがほどよいところがない - dc.SetBackgroundMode(wxSOLID); - dc.SetTextForeground(text_fgcolor); dc.SetTextBackground(text_bgcolor); @@ -286,7 +315,8 @@ WXTextPanel::KanjiBitmap(uint16 sjiscode int code = jh * 94 + jl; // XXX 見付からなかったらゲタ文字にしたい - if (code <0) code=0x6b; + if (code < 0) + code=0x6b; // フォント領域 const uint8 *base;