MiniTerminal can redraw itself.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12630 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2005-05-11 10:26:35 +00:00
parent 3a5624e900
commit 8b0aee9f12
2 changed files with 144 additions and 16 deletions

View File

@ -9,6 +9,8 @@
* Distributed under the terms of the MIT License.
*/
#include <string.h>
#include "ViewBuffer.h"
#define CHAR_WIDTH 7
@ -38,18 +40,17 @@ static uint32 sPalette32[] = {
ViewBuffer::ViewBuffer(BRect frame)
: BView(frame, "ViewBuffer", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS)
: BView(frame, "ViewBuffer", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS),
fColumns(frame.IntegerWidth() / CHAR_WIDTH),
fRows(frame.IntegerHeight() / CHAR_HEIGHT),
fGlyphGrid(NULL),
fResizeCallback(NULL),
// initially, the cursor is hidden
fCursorX(-1),
fCursorY(-1)
{
SetFont(be_fixed_font);
fColumns = frame.IntegerWidth() / CHAR_WIDTH;
fRows = frame.IntegerHeight() / CHAR_HEIGHT;
fResizeCallback = NULL;
// initially, the cursor is hidden
fCursorX = -1;
fCursorY = -1;
// initialize private palette
for (int i = 0; i < 8; i++) {
fPalette[i].red = (sPalette32[i] >> 16) & 0xff;
@ -57,20 +58,51 @@ ViewBuffer::ViewBuffer(BRect frame)
fPalette[i].blue = (sPalette32[i] >> 0) & 0xff;
fPalette[i].alpha = 0xff;
}
// initialize glyph grid
uint32 size = fRows * fColumns;
if (size > 0) {
fGlyphGrid = new uint16[size];
memset(fGlyphGrid, 0, size * sizeof(uint16));
}
}
ViewBuffer::~ViewBuffer()
{
delete[] fGlyphGrid;
}
void
ViewBuffer::FrameResized(float width, float height)
{
int32 oldColumns = fColumns;
int32 oldRows = fRows;
fColumns = (int32)width / CHAR_WIDTH;
fRows = (int32)height / CHAR_HEIGHT;
// resize glyph grid
uint16* oldGlyphGrid = fGlyphGrid;
uint32 size = fRows * fColumns;
if (size > 0) {
fGlyphGrid = new uint16[size];
memset(fGlyphGrid, 0, size * sizeof(uint16));
} else
fGlyphGrid = NULL;
// transfer old glyph grid into new one
if (oldGlyphGrid && fGlyphGrid) {
int32 columns = min_c(oldColumns, fColumns);
int32 rows = min_c(oldRows, fRows);
for (int32 y = 0; y < rows; y++) {
for (int32 x = 0; x < columns; x++) {
fGlyphGrid[y * fColumns + x] = oldGlyphGrid[y * oldColumns + x];
}
}
}
delete[] oldGlyphGrid;
if (fResizeCallback)
fResizeCallback(fColumns, fRows, fResizeCallbackData);
}
@ -149,20 +181,46 @@ ViewBuffer::FillGlyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph,
void
ViewBuffer::RenderGlyph(int32 x, int32 y, uint8 glyph, uint8 attr)
{
BPoint where(x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 3);
char string[2];
string[0] = glyph;
string[1] = 0;
if (LockLooper()) {
SetHighColor(GetPaletteEntry(ForegroundColor(attr)));
SetLowColor(GetPaletteEntry(BackgroundColor(attr)));
FillRect(BRect(x * CHAR_WIDTH, y * CHAR_HEIGHT, (x + 1) * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT), B_SOLID_LOW);
DrawString(string, where);
_RenderGlyph(x, y, string, attr);
Sync();
UnlockLooper();
}
// remember the glyph in the grid
if (fGlyphGrid) {
fGlyphGrid[y * fColumns + x] = (glyph << 8) | attr;
}
}
void
ViewBuffer::Draw(BRect updateRect)
{
if (fGlyphGrid) {
int32 startX = max_c(0, (int32)(updateRect.left / CHAR_WIDTH));
int32 endX = min_c(fColumns - 1, (int32)(updateRect.right / CHAR_WIDTH) + 1);
int32 startY = max_c(0, (int32)(updateRect.top / CHAR_HEIGHT));
int32 endY = min_c(fRows - 1, (int32)(updateRect.bottom / CHAR_HEIGHT) + 1);
char string[2];
string[1] = 0;
for (int32 y = startY; y <= endY; y++) {
for (int32 x = startX; x <= endX; x++) {
uint16 grid = fGlyphGrid[y * fColumns + x];
uint8 glyph = grid >> 8;
uint8 attr = grid & 0x00ff;
string[0] = glyph;
_RenderGlyph(x, y, string, attr, false);
}
}
}
DrawCursor(fCursorX, fCursorY);
}
@ -197,6 +255,49 @@ ViewBuffer::MoveCursor(int32 x, int32 y)
void
ViewBuffer::Blit(int32 srcx, int32 srcy, int32 width, int32 height, int32 destx, int32 desty)
{
// blit inside the glyph grid
if (fGlyphGrid) {
int32 xOffset = destx - srcx;
int32 yOffset = desty - srcy;
int32 xIncrement;
int32 yIncrement;
uint16* src = fGlyphGrid + srcy * fColumns + srcx;
if (xOffset > 0) {
// copy from right to left
xIncrement = -1;
src += width - 1;
} else {
// copy from left to right
xIncrement = 1;
}
if (yOffset > 0) {
// copy from bottom to top
yIncrement = -fColumns;
src += (height - 1) * fColumns;
} else {
// copy from top to bottom
yIncrement = fColumns;
}
uint16* dst = src + yOffset * fColumns + xOffset;
for (int32 y = 0; y < height; y++) {
uint16* srcHandle = src;
uint16* dstHandle = dst;
for (int32 x = 0; x < width; x++) {
*dstHandle = *srcHandle;
srcHandle += xIncrement;
dstHandle += xIncrement;
}
src += yIncrement;
dst += yIncrement;
}
}
height *= CHAR_HEIGHT;
width *= CHAR_WIDTH;
@ -229,4 +330,24 @@ ViewBuffer::Clear(uint8 attr)
fCursorX = -1;
fCursorY = -1;
if (fGlyphGrid)
memset(fGlyphGrid, 0, fRows * fColumns * sizeof(uint16));
}
void
ViewBuffer::_RenderGlyph(int32 x, int32 y, const char* string, uint8 attr, bool fill)
{
BPoint where(x * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT - 3);
SetHighColor(GetPaletteEntry(ForegroundColor(attr)));
if (fill) {
SetLowColor(GetPaletteEntry(BackgroundColor(attr)));
FillRect(BRect(x * CHAR_WIDTH, y * CHAR_HEIGHT,
(x + 1) * CHAR_WIDTH, (y + 1) * CHAR_HEIGHT),
B_SOLID_LOW);
}
DrawString(string, where);
}

View File

@ -23,6 +23,8 @@ virtual void FrameResized(float new_width, float new_height);
void FillGlyph(int32 x, int32 y, int32 width, int32 height, uint8 glyph, uint8 attr);
void RenderGlyph(int32 x, int32 y, uint8 glyph, uint8 attr);
virtual void Draw(BRect updateRect);
void DrawCursor(int32 x, int32 y);
void MoveCursor(int32 x, int32 y);
@ -30,8 +32,13 @@ virtual void FrameResized(float new_width, float new_height);
void Clear(uint8 attr);
private:
void _RenderGlyph(int32 x, int32 y, const char* string, uint8 attr, bool fill = true);
int32 fColumns;
int32 fRows;
uint16* fGlyphGrid;
resize_callback fResizeCallback;
void *fResizeCallbackData;
int32 fCursorX;