Annotation of nono/wx/wxtextscreen.cpp, revision 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.