--- nono/wx/wxtextpanel.cpp 2026/04/29 17:04:39 1.1.1.4 +++ nono/wx/wxtextpanel.cpp 2026/04/29 17:04:53 1.1.1.5 @@ -9,15 +9,7 @@ #include "bitrev.h" #include "cgrom.h" #include "kaname12.h" - -// wxOSX(-3.0.2) の wxLIGHT_GREY は値が(色も透明度も)正しくない。 -// wxGTK の wxLIGHT_GREY は 0xffd3d3d3 だけどこれを Mac で見ると -// (Mac の統一感としては) 暗く見えるので色コード自体を変える。 -#if defined(__WXOSX__) -#define LIGHT_GREY wxColour(0xffe0e0e0) -#else -#define LIGHT_GREY *wxLIGHT_GREY -#endif +#include "sjis.h" // // テキストフォントを管理するクラス @@ -30,14 +22,21 @@ static const wxSize fontinfo[] = { }; static_assert(countof(fontinfo) == FontId::Max, ""); -// コンストラクタ +// コンストラクタ (style 指定なし) +// (wxPanel の style のデフォルトは wxTAB_TRAVERSAL) WXTextPanel::WXTextPanel(wxWindow *parent) - : inherited(parent, wxID_ANY) + : WXTextPanel(parent, wxTAB_TRAVERSAL) +{ +} + +// コンストラクタ (style 指定あり) +WXTextPanel::WXTextPanel(wxWindow *parent, long style) + : inherited(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style) { UpdateFont(global_fontid); // デフォルト色 - SetTextColor(*wxBLACK, LIGHT_GREY, wxColour(0x50, 0x50, 0x50)); + ResetTextColor(); } // デストラクタ @@ -97,9 +96,11 @@ WXTextPanel::AllocFont(FontId fontid) wxBitmap **ascii_glyph = ascii_glyph_table[fontid]; wxBitmap **bold_glyph = bold_glyph_table[fontid]; - // ASCII というか半角というかは通常 0x7f までだが + // 半角文字領域 256 文字全部をキャッシュする。ASCII は 0x7f までだが // X680x0 の CGROM の 0x80, 0x81, 0x82 には '\\', '~', '|' が - // 収納されているのでここまで含めてデータを作っておく。 + // 収納されている。 + // また CGROM に収録されている半角ひらがなは使わないが、避けるのも + // 手間なのでここまで含めてデータを作っておく。 for (int ch = 0; ch < countof(ascii_glyph_table[0]); ch++) { const uint8 *ptr = base + ch * bytes; @@ -148,20 +149,26 @@ WXTextPanel::FreeFont(FontId fontid) } } +// テキスト色をデフォルトに設定する(戻す) +void +WXTextPanel::ResetTextColor() +{ + SetTextColor(*wxBLACK, BGPANEL); +} + // テキスト色を指定する void -WXTextPanel::SetTextColor(const wxColour& fg, const wxColour& bg, - const wxColour& dc) +WXTextPanel::SetTextColor(const wxColour& fg, const wxColour& bg) { text_fgcolor = fg; text_bgcolor = bg; - text_disable_color = dc; } // (px, py) を左上とする座標から Shift_JIS 文字列を属性 attr で描画する。 -// 文字列中で属性を変えることはできない。 -// キャンバスをはみ出すかどうかについてはこちらでは関知しない。 +// ただし attr のうちここで参照するのは EM (ボールド) かそうでないかのみ。 +// 描画色、背景色は事前に SetTextColor() で設定したもの。 // フォントサイズは現行のフォント。 +// キャンバスをはみ出すかどうかについてはこちらでは関知しない。 void WXTextPanel::DrawStringSJIS(wxDC& dc, int px, int py, const char *sjis, uint attr) @@ -169,14 +176,10 @@ WXTextPanel::DrawStringSJIS(wxDC& dc, in const uint8 *s; for (s = (const uint8 *)sjis; *s; ) { - if (__predict_true(*s < 0x80)) { - // ASCII + if (__predict_true(SJIS::IsHankaku(*s))) { + // 半角 DrawChar1(dc, px, py, *s++, attr); px += font_width; - } else if (0xa0 <= *s && *s < 0xe0) { - // 半角カナ - DrawCharKana(dc, px, py, *s++, attr); - px += font_width; } else { // 全角 int code; @@ -188,15 +191,15 @@ WXTextPanel::DrawStringSJIS(wxDC& dc, in } } -// (px, py) を左上とする座標からASCII文字 code を属性 attr で描画する。 -// code は 0x80 未満。 +// (px, py) を左上とする座標から半角文字 code を属性 attr で描画する。 +// code は ASCII または半角カナ。 // フォントサイズは現行のフォント。 void WXTextPanel::DrawChar1(wxDC& dc, int px, int py, uint code, uint attr) { wxBitmap **glyph; - assertmsg(code < 0x80, "code=0x%x", code); + assertmsg(code < 0x100, "code=0x%x", code); // ボールドかどうかでテーブルが別 if ((attr & TA::Em)) { @@ -219,17 +222,7 @@ WXTextPanel::DrawChar1(wxDC& dc, int px, code = 0x82; } } - DrawBitmap(dc, px, py, *glyph[code], attr); -} - -// (px, py) を左上とする座標から半角カナ1文字を出力する。 -// フォントサイズは現行のフォント。 -void -WXTextPanel::DrawCharKana(wxDC& dc, int px, int py, uint sjiscode, uint attr) -{ - std::unique_ptr kana; - kana.reset(KanaBitmap(sjiscode, attr)); - DrawBitmap(dc, px, py, *kana, attr); + DrawBitmap(dc, px, py, *glyph[code]); } // (px, py) を左上とする座標から漢字1文字を出力する。 @@ -240,78 +233,23 @@ WXTextPanel::DrawChar2(wxDC& dc, int px, { std::unique_ptr kanji; kanji.reset(KanjiBitmap(sjiscode, attr)); - DrawBitmap(dc, px, py, *kanji, attr); + DrawBitmap(dc, px, py, *kanji); } // (px, py) を左上とする座標に bitmap を描画する。 -// この DrawBitmap() は dc のペン色を設定して dc.DrawBitmap() を呼ぶ。 -// ちょっと紛らわしいので注意。 +// 前景色、背景色は事前に SetTextColor() で予約された色を使う。 void -WXTextPanel::DrawBitmap(wxDC& dc, int px, int py, const wxBitmap& bitmap, - uint attr) +WXTextPanel::DrawBitmap(wxDC& dc, int px, int py, const wxBitmap& bitmap) { // 文字の背景は透過ではなく背景色で塗りつぶす - // XXX もっと初期化時に近いところへ移してよさそうだが + // (そうしないと元あった文字の上に重なってしまう) + // XXX dc につき最初の1回だけでいいのだがほどよいところがない dc.SetBackgroundMode(wxSOLID); - // 属性を設定 - switch (attr) { - case TA::On: - dc.SetTextForeground(text_bgcolor); - dc.SetTextBackground(text_fgcolor); - break; - case TA::Disable: - dc.SetTextForeground(text_disable_color); - dc.SetTextBackground(text_bgcolor); - break; - default: - dc.SetTextForeground(text_fgcolor); - dc.SetTextBackground(text_bgcolor); - break; - } - - // 1文字出力 - dc.DrawBitmap(bitmap, px, py); - - // 1文字ずつ属性を元に戻す dc.SetTextForeground(text_fgcolor); dc.SetTextBackground(text_bgcolor); -} -// Shift_JIS の半角カナ1文字分のビットマップを作成する。 -wxBitmap * -WXTextPanel::KanaBitmap(uint16 sjiscode, uint attr) -{ - const uint8 *base; - // X680x0 CGROM - switch (fontid) { - case FontId::_6x12: - base = BuiltinCGROM::Get6x12(); - break; - case FontId::_8x16: - base = BuiltinCGROM::Get8x16(); - break; - default: - __unreachable(); - } - - int bytes = ((font_width + 7) / 8) * font_height; - std::vector buf(bytes); - - const uint8 *ptr; - ptr = base + sjiscode * bytes; - - for (int i = 0; i < bytes; i++) { - buf[i] = bitrev(ptr[i]); - } - if (attr == TA::Em) { - for (int i = 0; i < bytes; i++) { - buf[i] |= buf[i] >> 1; - } - } - - // その XBM データから1文字分のビットマップオブジェクトを作成 - return new wxBitmap(&buf[0], font_width, font_height, 1); + dc.DrawBitmap(bitmap, px, py); } // Shift_JIS の漢字1文字のビットマップを作成する。 @@ -389,5 +327,5 @@ WXTextPanel::KanjiBitmap(uint16 sjiscode FontId WXTextPanel::global_fontid; std::mutex WXTextPanel::global_font_mutex; u_int WXTextPanel::font_refcnt[FontId::Max]; -wxBitmap *WXTextPanel::ascii_glyph_table[FontId::Max][0x83]; -wxBitmap *WXTextPanel::bold_glyph_table[FontId::Max][0x83]; +wxBitmap *WXTextPanel::ascii_glyph_table[FontId::Max][256]; +wxBitmap *WXTextPanel::bold_glyph_table[FontId::Max][256];