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:
parent
3a5624e900
commit
8b0aee9f12
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user