|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.