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

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"
1.1.1.3 ! root        8: #include "wxmainframe.h"
1.1       root        9: #include "bitrev.h"
                     10: #include "cgrom.h"
                     11: 
                     12: //
1.1.1.3 ! root       13: // テキストスクリーンを表示するパネル
1.1       root       14: //
                     15: 
                     16: // イベントテーブル
                     17: wxBEGIN_EVENT_TABLE(WXTextScreen, inherited)
                     18:        EVT_PAINT(WXTextScreen::OnPaint)
                     19:        EVT_SIZE(WXTextScreen::OnSize)
1.1.1.3 ! root       20:        EVT_TIMER(wxID_ANY, WXTextScreen::OnTimer)
1.1       root       21: wxEND_EVENT_TABLE()
                     22: 
                     23: // コンストラクタ
1.1.1.3 ! root       24: WXTextScreen::WXTextScreen(wxWindow *parent, IMonitor& monitor_)
1.1       root       25:        : inherited(parent)
1.1.1.3 ! root       26:        , monitor(monitor_)
1.1       root       27: {
1.1.1.3 ! root       28:        // モニタサイズから初期サイズを決定
        !            29:        nnSize ms = monitor.GetMonitorSize();
        !            30:        wxSize size = wxSize(ms.width * font_width, ms.height * font_height);
        !            31:        SetClientSize(size);
        !            32:        SetMinSize(size);
        !            33: 
        !            34:        timer.SetOwner(this);
1.1       root       35: 
1.1.1.3 ! root       36:        // 現在の設定値を適用
        !            37:        SetRate(gMainFrame->GetMonitorRate());
        !            38: 
        !            39:        // 最初に一回描画を起こす
        !            40:        wxTimerEvent dummy;
        !            41:        AddPendingEvent(dummy);
1.1       root       42: }
                     43: 
                     44: // デストラクタ
                     45: WXTextScreen::~WXTextScreen()
                     46: {
1.1.1.2   root       47:        bitmap.reset();
                     48:        image.reset();
                     49:        bmpbuf.reset();
                     50:        prevbuf.reset();
1.1       root       51: }
                     52: 
1.1.1.3 ! root       53: // 画面更新頻度を Hz で設定する。
1.1       root       54: void
1.1.1.3 ! root       55: WXTextScreen::SetRate(int hz)
1.1       root       56: {
1.1.1.3 ! root       57:        timer.Start(1000 / hz);
1.1       root       58: }
                     59: 
                     60: // フォントサイズ変更 (外部インタフェース)
                     61: void
1.1.1.3 ! root       62: WXTextScreen::SetFontSize(FontId new_fontid)
1.1       root       63: {
                     64:        // 同じなら何もしない
1.1.1.3 ! root       65:        if (fontid == new_fontid) {
1.1       root       66:                return;
                     67:        }
                     68: 
                     69:        // フォントを更新
1.1.1.3 ! root       70:        UpdateFont(new_fontid);
1.1       root       71: 
                     72:        // 再描画を強制する。
                     73:        // テキストの桁数行数は変わってないので再確保はしなくていい。
1.1.1.3 ! root       74:        int col = ts.GetCol();
        !            75:        int row = ts.GetRow();
1.1.1.2   root       76:        assert((bool)prevbuf);
                     77:        memset(&prevbuf[0], 0xff, col * row * sizeof(prevbuf[0]));
1.1       root       78: 
                     79:        // コントロールの大きさを変更
                     80:        wxSize size = wxSize(col * font_width, row * font_height);
                     81:        SetClientSize(size);
                     82:        SetMinSize(size);
                     83: }
                     84: 
                     85: // サイズ変更イベント
                     86: void
                     87: WXTextScreen::OnSize(wxSizeEvent& event)
                     88: {
                     89:        // Mac ではウィンドウ作成時に 0 以下の値が来ることがある
                     90:        // GTK では 1 で来ることがある
1.1.1.3 ! root       91:        const wxSize& size = event.GetSize();
1.1       root       92:        if (size.x <= 1 || size.y <= 1) {
                     93:                return;
                     94:        }
                     95: 
1.1.1.3 ! root       96:        // テキストサイズが変わった時だけテキストバッファを再構成。
        !            97:        // (フォントサイズを変えると桁数×行数が変わらず画面サイズが変わる
        !            98:        // ということは起きることに注意)
        !            99:        int col = size.x / font_width;
        !           100:        int row = size.y / font_height;
        !           101:        if (col != ts.GetCol() || row != ts.GetRow()) {
        !           102:                ts.Init(col, row);
        !           103:                prevbuf.reset(new uint16 [col * row]);
        !           104:                memset(&prevbuf[0], 0xff, col * row * sizeof(prevbuf[0]));
        !           105:        }
        !           106: 
        !           107:        // ビットマップサイズが変わった時だけビットマップバッファを再構成。
        !           108:        if (col * font_width != view_width || row * font_height != view_height) {
        !           109:                // ビットマップを持っていれば (この順序で) 一旦解放
        !           110:                bitmap.reset();
        !           111:                image.reset();
        !           112:                bmpbuf.reset();
        !           113: 
        !           114:                // ビットマップ作成
        !           115:                view_width  = col * font_width;
        !           116:                view_height = row * font_height;
        !           117:                bmpbuf.reset(new uint8 [view_width * view_height * 3]);
        !           118:                // 正しく描かれなかった時に分かりやすいよう初期値は濃いグレーにしておく
        !           119:                memset(&bmpbuf[0], 0x70, view_width * view_height * 3);
        !           120:                image.reset(new wxImage(view_width, view_height, bmpbuf.get(), true));
        !           121:                bitmap.reset(new wxBitmap(*image));
        !           122:        }
        !           123: }
1.1       root      124: 
1.1.1.3 ! root      125: // タイマーイベント
        !           126: void
        !           127: WXTextScreen::OnTimer(wxTimerEvent& event)
        !           128: {
        !           129:        // モニタースクリーンを更新して再描画。
        !           130:        monitor.MonitorUpdate(ts);
        !           131:        RefreshIfUpdated();
        !           132: }
1.1       root      133: 
1.1.1.3 ! root      134: // 必要なら画面を更新して再描画する
        !           135: void
        !           136: WXTextScreen::RefreshIfUpdated()
        !           137: {
        !           138:        int len = ts.GetCol() * ts.GetRow() * sizeof(prevbuf[0]);
        !           139:        if (memcmp(ts.GetBuf(), &prevbuf[0], len) != 0) {
        !           140:                Refresh();
        !           141:        }
1.1       root      142: }
                    143: 
                    144: // 描画イベント (UI スレッドから呼ばれる)
                    145: void
                    146: WXTextScreen::OnPaint(wxPaintEvent& event)
                    147: {
1.1.1.3 ! root      148:        // メモリ DC に描画
1.1       root      149:        wxMemoryDC memDC;
                    150:        memDC.SelectObject(*bitmap);
1.1.1.3 ! root      151:        // 基本的には RefreshIfUpdated() により更新があった時だけ呼ばれる
        !           152:        Draw(memDC);
1.1       root      153: 
                    154:        // 実画面 DC にコピー
                    155:        wxPaintDC dstDC(this);
                    156:        dstDC.Blit(0, 0, view_width, view_height, &memDC, 0, 0);
                    157: }
                    158: 
                    159: // テキストバッファの内容をパネルのバックグラウンドバッファに描画する。
                    160: void
                    161: WXTextScreen::Draw(wxDC& dc)
                    162: {
1.1.1.3 ! root      163:        const uint16 *text = ts.GetBuf();
1.1.1.2   root      164:        uint16 *prev = &prevbuf[0];
1.1.1.3 ! root      165:        int col = ts.GetCol();
        !           166:        int row = ts.GetRow();
1.1       root      167:        int px = 0;
                    168:        int py = 0;
                    169:        for (int y = 0; y < row; y++, py += font_height) {
                    170:                px = 0;
                    171:                for (int x = 0; x < col; ) {
                    172:                        uint16 data = *text;
                    173:                        uint attr = (data & 0xff00);
                    174:                        uint chr  = (data & 0xff);
                    175:                        if (__predict_true(chr < 128)) {
                    176:                                // ASCII
                    177:                                if (*prev != data) {
                    178:                                        DrawChar1(dc, px, py, chr, attr);
                    179:                                        *prev = data;
                    180:                                }
                    181:                                prev++;
                    182:                                text++;
                    183:                                x++;
                    184:                                px += font_width;
                    185:                        } else {
                    186:                                // マルチバイト文字は Shift_JIS として処理する
                    187:                                uint code = (chr << 8) | (text[1] & 0xff);
1.1.1.3 ! root      188:                                if (prev[0] != data || prev[1] != text[1]) {
1.1       root      189:                                        DrawChar2(dc, px, py, code, attr);
                    190:                                }
                    191:                                *prev++ = *text++;
                    192:                                *prev++ = *text++;
                    193:                                x += 2;
                    194:                                px += font_width * 2;
                    195:                        }
                    196:                }
                    197:        }
                    198: }

unix.superglobalmegacorp.com

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