summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/grey_draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lib/grey_draw.c')
-rw-r--r--apps/plugins/lib/grey_draw.c300
1 files changed, 187 insertions, 113 deletions
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c
index 3b81694..171d273 100644
--- a/apps/plugins/lib/grey_draw.c
+++ b/apps/plugins/lib/grey_draw.c
@@ -28,16 +28,18 @@
#include "plugin.h"
#include "grey.h"
+extern struct viewport _grey_default_vp;
+
/*** low-level drawing functions ***/
static void setpixel(unsigned char *address)
{
- *address = _grey_info.fg_brightness;
+ *address = _GREY_FG_BRIGHTNESS(_grey_info.vp);
}
static void clearpixel(unsigned char *address)
{
- *address = _grey_info.bg_brightness;
+ *address = _GREY_BG_BRIGHTNESS(_grey_info.vp);
}
static void flippixel(unsigned char *address)
@@ -57,35 +59,56 @@ void (* const _grey_pixelfuncs[8])(unsigned char *address) = {
/*** Drawing functions ***/
+/* Clear the current viewport */
+void grey_clear_viewport(void)
+{
+ struct viewport *vp = _grey_info.vp;
+ int drawmode = vp->drawmode;
+ vp->drawmode = DRMODE_SOLID | DRMODE_INVERSEVID;
+ grey_fillrect(0, 0, vp->width, vp->height);
+ vp->drawmode = drawmode;
+}
+
/* Clear the whole display */
void grey_clear_display(void)
{
- int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ?
- _grey_info.fg_brightness : _grey_info.bg_brightness;
+ struct viewport *vp = &_grey_default_vp;
- rb->memset(_grey_info.buffer, value,
- _GREY_MULUQ(_grey_info.width, _grey_info.height));
+ int value = (vp->drawmode & DRMODE_INVERSEVID) ?
+ _GREY_FG_BRIGHTNESS(vp) : _GREY_BG_BRIGHTNESS(vp);
+
+ rb->memset(_grey_info.curbuffer, value,
+ _GREY_MULUQ(_grey_info.cb_width, _grey_info.cb_height));
}
/* Set a single pixel */
void grey_drawpixel(int x, int y)
{
- if (((unsigned)x < (unsigned)_grey_info.width)
- && ((unsigned)y < (unsigned)_grey_info.height))
- _grey_pixelfuncs[_grey_info.drawmode](&_grey_info.buffer[_GREY_MULUQ(
- _grey_info.width, y) + x]);
+ if (x >= _grey_info.clip_l && x < _grey_info.clip_r &&
+ y >= _grey_info.clip_t && y < _grey_info.clip_b)
+ {
+ int dst_stride = _grey_info.cb_width;
+ struct viewport *vp = _grey_info.vp;
+ _grey_pixelfuncs[vp->drawmode](
+ &_grey_info.curbuffer[
+ _GREY_MULUQ(dst_stride, vp->y - _grey_info.cb_y + y) +
+ vp->x - _grey_info.cb_x + x]);
+ }
}
/* Draw a line */
void grey_drawline(int x1, int y1, int x2, int y2)
{
+ struct viewport *vp = _grey_info.vp;
int numpixels;
int i;
int deltax, deltay;
int d, dinc1, dinc2;
int x, xinc1, xinc2;
int y, yinc1, yinc2;
- void (*pfunc)(unsigned char *address) = _grey_pixelfuncs[_grey_info.drawmode];
+ void (*pfunc)(unsigned char *address) = _grey_pixelfuncs[vp->drawmode];
+ int dwidth;
+ int xoffs, yoffs;
deltax = abs(x2 - x1);
deltay = abs(y2 - y1);
@@ -127,11 +150,18 @@ void grey_drawline(int x1, int y1, int x2, int y2)
x = x1;
y = y1;
+ dwidth = _grey_info.cb_width;
+ xoffs = vp->x - _grey_info.cb_x;
+ yoffs = vp->y - _grey_info.cb_y;
+
for (i = 0; i < numpixels; i++)
{
- if (((unsigned)x < (unsigned)_grey_info.width)
- && ((unsigned)y < (unsigned)_grey_info.height))
- pfunc(&_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]);
+ if (x >= _grey_info.clip_l && x < _grey_info.clip_r &&
+ y >= _grey_info.clip_t && y < _grey_info.clip_b)
+ {
+ pfunc(&_grey_info.curbuffer[_GREY_MULUQ(dwidth, yoffs + y) +
+ xoffs + x]);
+ }
if (d < 0)
{
@@ -151,10 +181,12 @@ void grey_drawline(int x1, int y1, int x2, int y2)
/* Draw a horizontal line (optimised) */
void grey_hline(int x1, int x2, int y)
{
+ struct viewport *vp = _grey_info.vp;
int x;
int value = 0;
unsigned char *dst;
bool fillopt = false;
+ int dwidth;
/* direction flip */
if (x2 < x1)
@@ -165,37 +197,40 @@ void grey_hline(int x1, int x2, int y)
}
/* nothing to draw? */
- if (((unsigned)y >= (unsigned)_grey_info.height)
- || (x1 >= _grey_info.width) || (x2 < 0))
+ if (y < _grey_info.clip_t || y >= _grey_info.clip_b ||
+ x1 >= _grey_info.clip_r || x2 < _grey_info.clip_l)
return;
/* drawmode and optimisation */
- if (_grey_info.drawmode & DRMODE_INVERSEVID)
+ if (vp->drawmode & DRMODE_INVERSEVID)
{
- if (_grey_info.drawmode & DRMODE_BG)
+ if (vp->drawmode & DRMODE_BG)
{
fillopt = true;
- value = _grey_info.bg_brightness;
+ value = _GREY_BG_BRIGHTNESS(vp);
}
}
else
{
- if (_grey_info.drawmode & DRMODE_FG)
+ if (vp->drawmode & DRMODE_FG)
{
fillopt = true;
- value = _grey_info.fg_brightness;
+ value = _GREY_FG_BRIGHTNESS(vp);
}
}
- if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT)
+ if (!fillopt && vp->drawmode != DRMODE_COMPLEMENT)
return;
/* clipping */
- if (x1 < 0)
- x1 = 0;
- if (x2 >= _grey_info.width)
- x2 = _grey_info.width - 1;
+ if (x1 < _grey_info.clip_l)
+ x1 = _grey_info.clip_l;
+ if (x2 >= _grey_info.clip_r)
+ x2 = _grey_info.clip_r - 1;
- dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1];
+ dwidth = _grey_info.cb_width;
+ dst = &_grey_info.curbuffer[
+ _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y) +
+ vp->x - _grey_info.cb_x + x1];
if (fillopt)
rb->memset(dst, value, x2 - x1 + 1);
@@ -211,9 +246,11 @@ void grey_hline(int x1, int x2, int y)
/* Draw a vertical line (optimised) */
void grey_vline(int x, int y1, int y2)
{
+ struct viewport *vp = _grey_info.vp;
int y;
unsigned char *dst, *dst_end;
void (*pfunc)(unsigned char *address);
+ int dwidth;
/* direction flip */
if (y2 < y1)
@@ -224,24 +261,27 @@ void grey_vline(int x, int y1, int y2)
}
/* nothing to draw? */
- if (((unsigned)x >= (unsigned)_grey_info.width)
- || (y1 >= _grey_info.height) || (y2 < 0))
+ if (x < _grey_info.clip_l || x >= _grey_info.clip_r ||
+ y1 >= _grey_info.clip_b || y2 < _grey_info.clip_t)
return;
/* clipping */
- if (y1 < 0)
- y1 = 0;
- if (y2 >= _grey_info.height)
- y2 = _grey_info.height - 1;
-
- pfunc = _grey_pixelfuncs[_grey_info.drawmode];
- dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y1) + x];
-
- dst_end = dst + _GREY_MULUQ(_grey_info.width, y2 - y1);
+ if (y1 < _grey_info.clip_t)
+ y1 = _grey_info.clip_t;
+ if (y2 >= _grey_info.clip_b)
+ y2 = _grey_info.clip_b - 1;
+
+ dwidth = _grey_info.cb_width;
+ pfunc = _grey_pixelfuncs[vp->drawmode];
+ dst = &_grey_info.curbuffer[
+ _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y1) +
+ vp->x - _grey_info.cb_x + x];
+
+ dst_end = dst + _GREY_MULUQ(dwidth, y2 - y1);
do
{
pfunc(dst);
- dst += _grey_info.width;
+ dst += dwidth;
}
while (dst <= dst_end);
}
@@ -334,53 +374,63 @@ void grey_drawrect(int x, int y, int width, int height)
/* Fill a rectangular area */
void grey_fillrect(int x, int y, int width, int height)
{
+ struct viewport *vp = _grey_info.vp;
int value = 0;
unsigned char *dst, *dst_end;
bool fillopt = false;
-
- /* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
- || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
- return;
+ int dwidth;
/* drawmode and optimisation */
- if (_grey_info.drawmode & DRMODE_INVERSEVID)
+ if (vp->drawmode & DRMODE_INVERSEVID)
{
- if (_grey_info.drawmode & DRMODE_BG)
+ if (vp->drawmode & DRMODE_BG)
{
fillopt = true;
- value = _grey_info.bg_brightness;
+ value = _GREY_BG_BRIGHTNESS(vp);
}
}
else
{
- if (_grey_info.drawmode & DRMODE_FG)
+ if (vp->drawmode & DRMODE_FG)
{
fillopt = true;
- value = _grey_info.fg_brightness;
+ value = _GREY_FG_BRIGHTNESS(vp);
+
}
}
- if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT)
+ if (!fillopt && vp->drawmode != DRMODE_COMPLEMENT)
return;
/* clipping */
- if (x < 0)
+ if (x < _grey_info.clip_l)
{
- width += x;
- x = 0;
+ width += x - _grey_info.clip_l;
+ x = _grey_info.clip_l;
}
- if (y < 0)
+
+ if (x + width > _grey_info.clip_r)
+ width = _grey_info.clip_r - x;
+
+ if (width <= 0)
+ return;
+
+ if (y < _grey_info.clip_t)
{
- height += y;
- y = 0;
+ height += y - _grey_info.clip_t;
+ y = _grey_info.clip_t;
}
- if (x + width > _grey_info.width)
- width = _grey_info.width - x;
- if (y + height > _grey_info.height)
- height = _grey_info.height - y;
+
+ if (y + height > _grey_info.clip_b)
+ height = _grey_info.clip_b - y;
+
+ if (height <= 0)
+ return;
- dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x];
- dst_end = dst + _GREY_MULUQ(_grey_info.width, height);
+ dwidth = _grey_info.cb_width;
+ dst = &_grey_info.curbuffer[
+ _GREY_MULUQ(dwidth, _grey_info.vp->y - _grey_info.cb_y + y) +
+ _grey_info.vp->x - _grey_info.cb_x + x];
+ dst_end = dst + _GREY_MULUQ(dwidth, height);
do
{
@@ -395,7 +445,7 @@ void grey_fillrect(int x, int y, int width, int height)
*dst_row = ~(*dst_row);
while (++dst_row < row_end);
}
- dst += _grey_info.width;
+ dst += dwidth;
}
while (dst < dst_end);
}
@@ -413,40 +463,49 @@ void grey_fillrect(int x, int y, int width, int height)
void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
+ struct viewport *vp = _grey_info.vp;
const unsigned char *src_end;
unsigned char *dst, *dst_end;
unsigned dmask = 0x100; /* bit 8 == sentinel */
- int drmode = _grey_info.drawmode;
+ int drmode = vp->drawmode;
int dwidth;
- /* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
- || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
- return;
-
/* clipping */
- if (x < 0)
+ if (x < _grey_info.clip_l)
{
- width += x;
- src_x -= x;
- x = 0;
+ int dx = x - _grey_info.clip_l;
+ width += dx;
+ src_x -= dx;
+ x = _grey_info.clip_l;
}
- if (y < 0)
+
+ if (x + width > _grey_info.clip_r)
+ width = _grey_info.clip_r - x;
+
+ if (width <= 0)
+ return;
+
+ if (y < _grey_info.clip_t)
{
- height += y;
- src_y -= y;
- y = 0;
+ int dy = y - _grey_info.clip_t;
+ height += dy;
+ src_y += dy;
+ y = _grey_info.clip_t;
}
- if (x + width > _grey_info.width)
- width = _grey_info.width - x;
- if (y + height > _grey_info.height)
- height = _grey_info.height - y;
+
+ if (y + height > _grey_info.clip_b)
+ height = _grey_info.clip_b - y;
+
+ if (height <= 0)
+ return;
src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */
src_y &= 7;
src_end = src + width;
- dwidth = _grey_info.width;
- dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x];
+ dwidth = _grey_info.cb_width;
+ dst = &_grey_info.curbuffer[
+ _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y) +
+ vp->x - _grey_info.cb_x + x];
dst_end = dst + _GREY_MULUQ(dwidth, height);
if (drmode & DRMODE_INVERSEVID)
@@ -485,7 +544,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
break;
case DRMODE_BG:
- bg = _grey_info.bg_brightness;
+ bg = _GREY_BG_BRIGHTNESS(vp);
do
{
if (!(data & 0x01))
@@ -498,7 +557,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
break;
case DRMODE_FG:
- fg = _grey_info.fg_brightness;
+ fg = _GREY_FG_BRIGHTNESS(vp);
do
{
if (data & 0x01)
@@ -511,8 +570,8 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
break;
case DRMODE_SOLID:
- fg = _grey_info.fg_brightness;
- bg = _grey_info.bg_brightness;
+ fg = _GREY_FG_BRIGHTNESS(vp);
+ bg = _GREY_BG_BRIGHTNESS(vp);
do
{
*dst_col = (data & 0x01) ? fg : bg;
@@ -537,38 +596,48 @@ void grey_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
unsigned char *dst, *dst_end;
-
- /* nothing to draw? */
- if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
- || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
- return;
+ int dwidth;
/* clipping */
- if (x < 0)
+ if (x < _grey_info.clip_l)
{
- width += x;
- src_x -= x;
- x = 0;
+ int dx = x - _grey_info.clip_l;
+ width += dx;
+ src_x -= dx;
+ x = _grey_info.clip_l;
}
+
+ if (x + width > _grey_info.clip_r)
+ width = _grey_info.clip_r - x;
+
+ if (width <= 0)
+ return;
+
if (y < 0)
{
- height += y;
- src_y -= y;
- y = 0;
+ int dy = y - _grey_info.clip_t;
+ height += dy;
+ src_y -= dy;
+ y = _grey_info.clip_t;
}
- if (x + width > _grey_info.width)
- width = _grey_info.width - x;
- if (y + height > _grey_info.height)
- height = _grey_info.height - y;
- src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */
- dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x];
- dst_end = dst + _GREY_MULUQ(_grey_info.width, height);
+ if (y + height > _grey_info.clip_b)
+ height = _grey_info.clip_b - y;
+
+ if (height <= 0)
+ return;
+
+ dwidth = _grey_info.cb_width;
+ src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */
+ dst = &_grey_info.curbuffer[
+ _GREY_MULUQ(dwidth, _grey_info.vp->y - _grey_info.cb_y + y) +
+ _grey_info.vp->x - _grey_info.cb_x + x];
+ dst_end = dst + _GREY_MULUQ(dwidth, height);
do
{
rb->memcpy(dst, src, width);
- dst += _grey_info.width;
+ dst += dwidth;
src += stride;
}
while (dst < dst_end);
@@ -586,11 +655,15 @@ void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str)
{
int ch;
unsigned short *ucs;
- struct font* pf = rb->font_get(_grey_info.curfont);
-
+ struct font* pf;
+
+ if (_grey_info.clip_b <= _grey_info.clip_t)
+ return;
+
+ pf = rb->font_get(_grey_info.vp->font);
ucs = rb->bidi_l2v(str, 1);
- while ((ch = *ucs++) != 0 && x < _grey_info.width)
+ while ((ch = *ucs++) != 0 && x < _grey_info.clip_r)
{
int width;
const unsigned char *bits;
@@ -624,9 +697,10 @@ void grey_putsxy(int x, int y, const unsigned char *str)
/* Clear the greyscale display (sets all pixels to white) */
void grey_ub_clear_display(void)
{
- int value = _grey_info.gvalue[(_grey_info.drawmode & DRMODE_INVERSEVID) ?
- _grey_info.fg_brightness :
- _grey_info.bg_brightness];
+ struct viewport *vp = &_grey_default_vp;
+ int value = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ?
+ _GREY_FG_BRIGHTNESS(vp) :
+ _GREY_BG_BRIGHTNESS(vp)];
rb->memset(_grey_info.values, value,
_GREY_MULUQ(_grey_info.width, _grey_info.height));