--- nono/wx/wxtextpanel.cpp 2026/04/29 17:04:33 1.1.1.2 +++ nono/wx/wxtextpanel.cpp 2026/04/29 17:04:37 1.1.1.3 @@ -1,13 +1,14 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "wxheader.h" -#include "wxcolor.h" #include "wxtextpanel.h" -#include "cgrom.h" +#include "wxcolor.h" #include "bitrev.h" +#include "cgrom.h" +#include "kaname12.h" // wxOSX(-3.0.2) の wxLIGHT_GREY は値が(色も透明度も)正しくない。 // wxGTK の wxLIGHT_GREY は 0xffd3d3d3 だけどこれを Mac で見ると @@ -22,14 +23,13 @@ // テキストフォントを管理するクラス // -struct fontinfo { +static struct fontinfo { int width; int height; } fontinfo[] = { // 順序はヘッダの FONT_* 識別子の順と揃えること { 6, 12 }, { 8, 16 }, - { 12, 24 }, }; static_assert(countof(fontinfo) == FONT_MAX, ""); @@ -78,16 +78,13 @@ WXTextPanel::AllocFont(fontsize_t fontsi return; } - // 6x12, 8x16, 12x24 半角は X68030 CGROM にあるのでそれを使う + // 6x12, 8x16 半角は X68030 CGROM にあるのでそれを使う switch (fontsize) { case FONT_6x12: - base = builtin_cgrom + 0xbf400; + base = BuiltinCGROM::Get6x12(); break; case FONT_8x16: - base = builtin_cgrom + 0x3a800; - break; - case FONT_12x24: - base = builtin_cgrom + 0x3d000; + base = BuiltinCGROM::Get8x16(); break; default: assertmsg(0, "fontsize=%d", fontsize); @@ -98,7 +95,7 @@ WXTextPanel::AllocFont(fontsize_t fontsi int font_height = fontinfo[fontsize].height; int font_stride = (font_width + 7) / 8; int bytes = font_stride * font_height; - char buf[bytes]; + std::vector buf(bytes); wxBitmap **ascii_glyph = ascii_glyph_table[fontsize]; wxBitmap **bold_glyph = bold_glyph_table[fontsize]; @@ -115,14 +112,14 @@ WXTextPanel::AllocFont(fontsize_t fontsi buf[i] = bitrev(src); } // その XBM データから1文字分のビットマップオブジェクトを作成 - ascii_glyph[ch] = new wxBitmap(buf, font_width, font_height, 1); + ascii_glyph[ch] = new wxBitmap(&buf[0], font_width, font_height, 1); // 続いてボールドに加工 for (int i = 0; i < bytes; i++) { // XBM 形式は MSB が右なので左シフトすると一般的なボールド。 buf[i] |= ((uint8)buf[i] << 1); } - bold_glyph[ch] = new wxBitmap(buf, font_width, font_height, 1); + bold_glyph[ch] = new wxBitmap(&buf[0], font_width, font_height, 1); } } @@ -174,10 +171,14 @@ WXTextPanel::DrawStringSJIS(wxDC& dc, in const uint8 *s; for (s = (const uint8 *)sjis; *s; ) { - if (__predict_true(*s < 128)) { - // 半角 + if (__predict_true(*s < 0x80)) { + // ASCII 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; @@ -223,15 +224,25 @@ WXTextPanel::DrawChar1(wxDC& dc, int px, 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); +} + // (px, py) を左上とする座標から漢字1文字を出力する。 // sjiscode は Shift_JIS。 // フォントサイズは現行のフォント。 void WXTextPanel::DrawChar2(wxDC& dc, int px, int py, uint sjiscode, uint attr) { - wxBitmap *kanji = KanjiBitmap(sjiscode, attr); + std::unique_ptr kanji; + kanji.reset(KanjiBitmap(sjiscode, attr)); DrawBitmap(dc, px, py, *kanji, attr); - delete kanji; } // (px, py) を左上とする座標に bitmap を描画する。 @@ -269,6 +280,42 @@ WXTextPanel::DrawBitmap(wxDC& dc, int px dc.SetTextBackground(text_bgcolor); } +// Shift_JIS の半角カナ1文字分のビットマップを作成する。 +wxBitmap * +WXTextPanel::KanaBitmap(uint16 sjiscode, uint attr) +{ + const uint8 *base; + // X680x0 CGROM + switch (fontsize) { + case FONT_6x12: + base = BuiltinCGROM::Get6x12(); + break; + case FONT_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); +} + // Shift_JIS の漢字1文字のビットマップを作成する。 wxBitmap * WXTextPanel::KanjiBitmap(uint16 sjiscode, uint attr) @@ -314,11 +361,7 @@ WXTextPanel::KanjiBitmap(uint16 sjiscode break; case FONT_8x16: // 16x16 は X680x0 CGROM のを使う。 - base = builtin_cgrom + 0; - break; - case FONT_12x24: - // 24x24 は X680x0 CGROM のを使う。 - base = builtin_cgrom + 0x40000; + base = BuiltinCGROM::Get16x16(); break; default: // ここより先に必ず半角のほうでエラーが出るはず @@ -326,7 +369,7 @@ WXTextPanel::KanjiBitmap(uint16 sjiscode } int bytes = (((font_width * 2) + 7) / 8) * font_height; - char buf[bytes]; + std::vector buf(bytes); const uint8 *ptr; ptr = base + code * bytes; @@ -341,7 +384,7 @@ WXTextPanel::KanjiBitmap(uint16 sjiscode } // その XBM データから1文字分のビットマップオブジェクトを作成 - return new wxBitmap(buf, font_width * 2, font_height, 1); + return new wxBitmap(&buf[0], font_width * 2, font_height, 1); } // スタティック変数