libroot_debug: Merge guarded heap into libroot_debug.
[haiku.git] / src / tests / apps / miniterminal / ViewBuffer.cpp
blobd5d8ef25f2c1f921f9e164d00fa8b6b134eedb5b
1 /*
2 * ViewBuffer - Mimicing a frame buffer output - but using a BView.
3 * Based on frame_buffer_console.
5 * Copyright 2005 Michael Lotz. All rights reserved.
6 * Distributed under the Haiku License.
8 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
9 * Distributed under the terms of the MIT License.
12 #include <string.h>
14 #include "ViewBuffer.h"
16 #define CHAR_WIDTH 7
17 #define CHAR_HEIGHT 13
19 // Palette is (black and white are swapt like in normal BeOS Terminal)
20 // 0 - black,
21 // 1 - blue,
22 // 2 - green,
23 // 3 - cyan,
24 // 4 - red,
25 // 5 - magenta,
26 // 6 - yellow,
27 // 7 - white
28 // 8-15 - same but bright (we're ignoring those)
30 static uint32 sPalette32[] = {
31 0xffffff,
32 0x0000ff,
33 0x00ff00,
34 0x00ffff,
35 0xff0000,
36 0xff00ff,
37 0xffff00,
38 0x000000,
42 ViewBuffer::ViewBuffer(BRect frame)
43 : BView(frame, "ViewBuffer", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS),
44 fColumns(frame.IntegerWidth() / CHAR_WIDTH),
45 fRows(frame.IntegerHeight() / CHAR_HEIGHT),
46 fGlyphGrid(NULL),
47 fResizeCallback(NULL),
48 // initially, the cursor is hidden
49 fCursorX(-1),
50 fCursorY(-1)
52 SetFont(be_fixed_font);
54 // initialize private palette
55 for (int i = 0; i < 8; i++) {
56 fPalette[i].red = (sPalette32[i] >> 16) & 0xff;
57 fPalette[i].green = (sPalette32[i] >> 8) & 0xff;
58 fPalette[i].blue = (sPalette32[i] >> 0) & 0xff;
59 fPalette[i].alpha = 0xff;
62 // initialize glyph grid
63 uint32 size = fRows * fColumns;
64 if (size > 0) {
65 fGlyphGrid = new uint16[size];
66 memset(fGlyphGrid, 0, size * sizeof(uint16));
71 ViewBuffer::~ViewBuffer()
73 delete[] fGlyphGrid;
77 void
78 ViewBuffer::FrameResized(float width, float height)
80 int32 oldColumns = fColumns;
81 int32 oldRows = fRows;
83 fColumns = (int32)width / CHAR_WIDTH;
84 fRows = (int32)height / CHAR_HEIGHT;
86 // resize glyph grid
87 uint16* oldGlyphGrid = fGlyphGrid;
88 uint32 size = fRows * fColumns;
89 if (size > 0) {
90 fGlyphGrid = new uint16[size];
91 memset(fGlyphGrid, 0, size * sizeof(uint16));
92 } else
93 fGlyphGrid = NULL;
94 // transfer old glyph grid into new one
95 if (oldGlyphGrid && fGlyphGrid) {
96 int32 columns = min_c(oldColumns, fColumns);
97 int32 rows = min_c(oldRows, fRows);
98 for (int32 y = 0; y < rows; y++) {
99 for (int32 x = 0; x < columns; x++) {
100 fGlyphGrid[y * fColumns + x] = oldGlyphGrid[y * oldColumns + x];
104 delete[] oldGlyphGrid;
106 if (fResizeCallback)
107 fResizeCallback(fColumns, fRows, fResizeCallbackData);
111 status_t
112 ViewBuffer::GetSize(int32 *width, int32 *height)
114 *width = fColumns;
115 *height = fRows;
116 return B_OK;
120 void
121 ViewBuffer::SetResizeCallback(resize_callback callback, void *data)
123 fResizeCallback = callback;
124 fResizeCallbackData = data;
128 uint8
129 ViewBuffer::ForegroundColor(uint8 attr)
131 return attr & 0x7;
135 uint8
136 ViewBuffer::BackgroundColor(uint8 attr)
138 return (attr >> 4) & 0x7;
142 rgb_color
143 ViewBuffer::GetPaletteEntry(uint8 index)
145 return fPalette[index];
149 void
150 ViewBuffer::PutGlyph(int32 x, int32 y, uint8 glyph, uint8 attr)
152 if (x >= fColumns || y >= fRows)
153 return;
155 RenderGlyph(x, y, glyph, attr);
159 void
160 ViewBuffer::FillGlyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph, uint8 attr)
162 if (x >= fColumns || y >= fRows)
163 return;
165 int32 left = x + width;
166 if (left > fColumns)
167 left = fColumns;
169 int32 bottom = y + height;
170 if (bottom > fRows)
171 bottom = fRows;
173 for (; y < bottom; y++) {
174 for (int32 x2 = x; x2 < left; x2++) {
175 RenderGlyph(x2, y, glyph, attr);
181 void
182 ViewBuffer::RenderGlyph(int32 x, int32 y, uint8 glyph, uint8 attr)
184 char string[2];
185 string[0] = glyph;
186 string[1] = 0;
188 if (LockLooper()) {
189 _RenderGlyph(x, y, string, attr);
190 Sync();
191 UnlockLooper();
193 // remember the glyph in the grid
194 if (fGlyphGrid) {
195 fGlyphGrid[y * fColumns + x] = (glyph << 8) | attr;
200 void
201 ViewBuffer::Draw(BRect updateRect)
203 if (fGlyphGrid) {
204 int32 startX = max_c(0, (int32)(updateRect.left / CHAR_WIDTH));
205 int32 endX = min_c(fColumns - 1, (int32)(updateRect.right / CHAR_WIDTH) + 1);
206 int32 startY = max_c(0, (int32)(updateRect.top / CHAR_HEIGHT));
207 int32 endY = min_c(fRows - 1, (int32)(updateRect.bottom / CHAR_HEIGHT) + 1);
209 char string[2];
210 string[1] = 0;
212 for (int32 y = startY; y <= endY; y++) {
213 for (int32 x = startX; x <= endX; x++) {
214 uint16 grid = fGlyphGrid[y * fColumns + x];
215 uint8 glyph = grid >> 8;
216 uint8 attr = grid & 0x00ff;
217 string[0] = glyph;
218 _RenderGlyph(x, y, string, attr, false);
223 DrawCursor(fCursorX, fCursorY);
227 void
228 ViewBuffer::DrawCursor(int32 x, int32 y)
230 if (x < 0 || y < 0)
231 return;
233 x *= CHAR_WIDTH;
234 y *= CHAR_HEIGHT;
236 if (LockLooper()) {
237 InvertRect(BRect(x, y, x + CHAR_WIDTH, y + CHAR_HEIGHT));
238 Sync();
239 UnlockLooper();
244 void
245 ViewBuffer::MoveCursor(int32 x, int32 y)
247 DrawCursor(fCursorX, fCursorY);
248 DrawCursor(x, y);
250 fCursorX = x;
251 fCursorY = y;
255 void
256 ViewBuffer::Blit(int32 srcx, int32 srcy, int32 width, int32 height, int32 destx, int32 desty)
258 // blit inside the glyph grid
259 if (fGlyphGrid) {
260 int32 xOffset = destx - srcx;
261 int32 yOffset = desty - srcy;
263 int32 xIncrement;
264 int32 yIncrement;
266 uint16* src = fGlyphGrid + srcy * fColumns + srcx;
268 if (xOffset > 0) {
269 // copy from right to left
270 xIncrement = -1;
271 src += width - 1;
272 } else {
273 // copy from left to right
274 xIncrement = 1;
277 if (yOffset > 0) {
278 // copy from bottom to top
279 yIncrement = -fColumns;
280 src += (height - 1) * fColumns;
281 } else {
282 // copy from top to bottom
283 yIncrement = fColumns;
286 uint16* dst = src + yOffset * fColumns + xOffset;
288 for (int32 y = 0; y < height; y++) {
289 uint16* srcHandle = src;
290 uint16* dstHandle = dst;
291 for (int32 x = 0; x < width; x++) {
292 *dstHandle = *srcHandle;
293 srcHandle += xIncrement;
294 dstHandle += xIncrement;
296 src += yIncrement;
297 dst += yIncrement;
301 height *= CHAR_HEIGHT;
302 width *= CHAR_WIDTH;
304 srcx *= CHAR_WIDTH;
305 srcy *= CHAR_HEIGHT;
306 BRect source(srcx, srcy, srcx + width, srcy + height);
308 destx *= CHAR_WIDTH;
309 desty *= CHAR_HEIGHT;
310 BRect dest(destx, desty, destx + width, desty + height);
312 if (LockLooper()) {
313 CopyBits(source, dest);
314 Sync();
315 UnlockLooper();
320 void
321 ViewBuffer::Clear(uint8 attr)
323 if (LockLooper()) {
324 SetLowColor(GetPaletteEntry(BackgroundColor(attr)));
325 SetViewColor(LowColor());
326 FillRect(Frame(), B_SOLID_LOW);
327 Sync();
328 UnlockLooper();
331 fCursorX = -1;
332 fCursorY = -1;
334 if (fGlyphGrid)
335 memset(fGlyphGrid, 0, fRows * fColumns * sizeof(uint16));
339 void
340 ViewBuffer::_RenderGlyph(int32 x, int32 y, const char* string, uint8 attr, bool fill)
342 BPoint where(x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 3);
344 SetHighColor(GetPaletteEntry(ForegroundColor(attr)));
345 if (fill) {
346 SetLowColor(GetPaletteEntry(BackgroundColor(attr)));
347 FillRect(BRect(x * CHAR_WIDTH, y * CHAR_HEIGHT,
348 (x + 1) * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT),
349 B_SOLID_LOW);
351 DrawString(string, where);