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

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

unix.superglobalmegacorp.com

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