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