Annotation of nono/wx/wxtextscreen.cpp, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2018 [email protected]
                      4: //
                      5: 
                      6: #include "wxheader.h"
                      7: #include "wxtextscreen.h"
                      8: #include "bitrev.h"
                      9: #include "cgrom.h"
                     10: 
                     11: //
                     12: // テキストスクリーン風コントロール
                     13: //
                     14: 
                     15: // イベントテーブル
                     16: wxBEGIN_EVENT_TABLE(WXTextScreen, inherited)
                     17:        EVT_PAINT(WXTextScreen::OnPaint)
                     18:        EVT_SIZE(WXTextScreen::OnSize)
                     19: wxEND_EVENT_TABLE()
                     20: 
                     21: // コンストラクタ
                     22: WXTextScreen::WXTextScreen(wxWindow *parent, int arg_col, int arg_row,
                     23:        const uint16 *arg_textbuf)
                     24:        : inherited(parent)
                     25: {
                     26:        col = arg_col;
                     27:        row = arg_row;
                     28:        textbuf = arg_textbuf;
                     29: 
                     30:        SetTextSize(col, row);
                     31: }
                     32: 
                     33: // デストラクタ
                     34: WXTextScreen::~WXTextScreen()
                     35: {
                     36:        if (bitmap) {
                     37:                delete bitmap;
                     38:        }
                     39:        if (image) {
                     40:                delete image;
                     41:        }
                     42:        if (bmpbuf) {
                     43:                delete bmpbuf;
                     44:        }
                     45:        if (prevbuf) {
                     46:                delete[] prevbuf;
                     47:        }
                     48: }
                     49: 
                     50: // このパネルの(テキストでの)大きさを設定する。
                     51: void
                     52: WXTextScreen::SetTextSize(int acol, int arow)
                     53: {
                     54:        col = acol;
                     55:        row = arow;
                     56:        int width  = col * font_width;
                     57:        int height = row * font_height;
                     58: 
                     59:        if (wxSize(width, height) == wxSize(view_width, view_height)) {
                     60:                return;
                     61:        }
                     62: 
                     63:        // サイズ変更イベント側でやるか
                     64:        if (prevbuf) {
                     65:                delete[] prevbuf;
                     66:                prevbuf = NULL;
                     67:        }
                     68:        prevbuf = new uint16 [col * row];
                     69:        memset(prevbuf, 0xff, col * row * sizeof(*prevbuf));
                     70: 
                     71:        SetClientSize(width, height);
                     72:        SetMinSize(wxSize(width, height));
                     73: }
                     74: 
                     75: // フォントサイズ変更 (外部インタフェース)
                     76: void
                     77: WXTextScreen::SetFontSize(fontsize_t new_fontsize)
                     78: {
                     79:        // 同じなら何もしない
                     80:        if (fontsize == new_fontsize) {
                     81:                return;
                     82:        }
                     83: 
                     84:        // フォントを更新
                     85:        UpdateFont(new_fontsize);
                     86: 
                     87:        // 再描画を強制する。
                     88:        // テキストの桁数行数は変わってないので再確保はしなくていい。
                     89:        assert(prevbuf);
                     90:        memset(prevbuf, 0xff, col * row * sizeof(*prevbuf));
                     91: 
                     92:        // コントロールの大きさを変更
                     93:        wxSize size = wxSize(col * font_width, row * font_height);
                     94:        SetClientSize(size);
                     95:        SetMinSize(size);
                     96: }
                     97: 
                     98: // サイズ変更イベント
                     99: void
                    100: WXTextScreen::OnSize(wxSizeEvent& event)
                    101: {
                    102:        // Mac ではウィンドウ作成時に 0 以下の値が来ることがある
                    103:        // GTK では 1 で来ることがある
                    104:        wxSize size = event.GetSize();
                    105:        if (size.x <= 1 || size.y <= 1) {
                    106:                return;
                    107:        }
                    108: 
                    109:        view_width = size.x;
                    110:        view_height = size.y;
                    111: 
                    112:        // ビットマップを持っていれば一旦解放
                    113:        if (bitmap) {
                    114:                delete bitmap;
                    115:                bitmap = NULL;
                    116:        }
                    117:        if (image) {
                    118:                delete image;
                    119:                image = NULL;
                    120:        }
                    121:        if (bmpbuf) {
                    122:                delete bmpbuf;
                    123:                bmpbuf = NULL;
                    124:        }
                    125: 
                    126:        // ビットマップ作成
                    127:        // 正しく描かれなかった時に分かりやすいよう初期値は濃いグレーにしておく
                    128:        bmpbuf = new uint8 [view_width * view_height * 3];
                    129:        memset(bmpbuf, 0x70, view_width * view_height * 3);
                    130:        image = new wxImage(view_width, view_height, bmpbuf, true);
                    131:        bitmap = new wxBitmap(*image);
                    132: }
                    133: 
                    134: // 描画イベント (UI スレッドから呼ばれる)
                    135: void
                    136: WXTextScreen::OnPaint(wxPaintEvent& event)
                    137: {
                    138:        // 更新があればメモリ DC に描画
                    139:        wxMemoryDC memDC;
                    140:        memDC.SelectObject(*bitmap);
                    141:        if (memcmp(textbuf, prevbuf, col * row * sizeof(*prevbuf)) != 0) {
                    142:                Draw(memDC);
                    143:        }
                    144: 
                    145:        // 実画面 DC にコピー
                    146:        wxPaintDC dstDC(this);
                    147:        dstDC.Blit(0, 0, view_width, view_height, &memDC, 0, 0);
                    148: }
                    149: 
                    150: // テキストバッファの内容をパネルのバックグラウンドバッファに描画する。
                    151: void
                    152: WXTextScreen::Draw(wxDC& dc)
                    153: {
                    154:        const uint16 *text = textbuf;
                    155:        uint16 *prev = prevbuf;
                    156:        int px = 0;
                    157:        int py = 0;
                    158:        for (int y = 0; y < row; y++, py += font_height) {
                    159:                px = 0;
                    160:                for (int x = 0; x < col; ) {
                    161:                        uint16 data = *text;
                    162:                        uint attr = (data & 0xff00);
                    163:                        uint chr  = (data & 0xff);
                    164:                        if (__predict_true(chr < 128)) {
                    165:                                // ASCII
                    166:                                if (*prev != data) {
                    167:                                        DrawChar1(dc, px, py, chr, attr);
                    168:                                        *prev = data;
                    169:                                }
                    170:                                prev++;
                    171:                                text++;
                    172:                                x++;
                    173:                                px += font_width;
                    174:                        } else {
                    175:                                // マルチバイト文字は Shift_JIS として処理する
                    176:                                uint code = (chr << 8) | (text[1] & 0xff);
                    177:                                if (*(uint32 *)prev != *(uint32 *)text) {
                    178:                                        DrawChar2(dc, px, py, code, attr);
                    179:                                }
                    180:                                *prev++ = *text++;
                    181:                                *prev++ = *text++;
                    182:                                x += 2;
                    183:                                px += font_width * 2;
                    184:                        }
                    185:                }
                    186:        }
                    187: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.