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 3b81694426..171d2734cf 100644
--- a/apps/plugins/lib/grey_draw.c
+++ b/apps/plugins/lib/grey_draw.c
@@ -28,16 +28,18 @@
28#include "plugin.h" 28#include "plugin.h"
29#include "grey.h" 29#include "grey.h"
30 30
31extern struct viewport _grey_default_vp;
32
31/*** low-level drawing functions ***/ 33/*** low-level drawing functions ***/
32 34
33static void setpixel(unsigned char *address) 35static void setpixel(unsigned char *address)
34{ 36{
35 *address = _grey_info.fg_brightness; 37 *address = _GREY_FG_BRIGHTNESS(_grey_info.vp);
36} 38}
37 39
38static void clearpixel(unsigned char *address) 40static void clearpixel(unsigned char *address)
39{ 41{
40 *address = _grey_info.bg_brightness; 42 *address = _GREY_BG_BRIGHTNESS(_grey_info.vp);
41} 43}
42 44
43static void flippixel(unsigned char *address) 45static void flippixel(unsigned char *address)
@@ -57,35 +59,56 @@ void (* const _grey_pixelfuncs[8])(unsigned char *address) = {
57 59
58/*** Drawing functions ***/ 60/*** Drawing functions ***/
59 61
62/* Clear the current viewport */
63void grey_clear_viewport(void)
64{
65 struct viewport *vp = _grey_info.vp;
66 int drawmode = vp->drawmode;
67 vp->drawmode = DRMODE_SOLID | DRMODE_INVERSEVID;
68 grey_fillrect(0, 0, vp->width, vp->height);
69 vp->drawmode = drawmode;
70}
71
60/* Clear the whole display */ 72/* Clear the whole display */
61void grey_clear_display(void) 73void grey_clear_display(void)
62{ 74{
63 int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ? 75 struct viewport *vp = &_grey_default_vp;
64 _grey_info.fg_brightness : _grey_info.bg_brightness;
65 76
66 rb->memset(_grey_info.buffer, value, 77 int value = (vp->drawmode & DRMODE_INVERSEVID) ?
67 _GREY_MULUQ(_grey_info.width, _grey_info.height)); 78 _GREY_FG_BRIGHTNESS(vp) : _GREY_BG_BRIGHTNESS(vp);
79
80 rb->memset(_grey_info.curbuffer, value,
81 _GREY_MULUQ(_grey_info.cb_width, _grey_info.cb_height));
68} 82}
69 83
70/* Set a single pixel */ 84/* Set a single pixel */
71void grey_drawpixel(int x, int y) 85void grey_drawpixel(int x, int y)
72{ 86{
73 if (((unsigned)x < (unsigned)_grey_info.width) 87 if (x >= _grey_info.clip_l && x < _grey_info.clip_r &&
74 && ((unsigned)y < (unsigned)_grey_info.height)) 88 y >= _grey_info.clip_t && y < _grey_info.clip_b)
75 _grey_pixelfuncs[_grey_info.drawmode](&_grey_info.buffer[_GREY_MULUQ( 89 {
76 _grey_info.width, y) + x]); 90 int dst_stride = _grey_info.cb_width;
91 struct viewport *vp = _grey_info.vp;
92 _grey_pixelfuncs[vp->drawmode](
93 &_grey_info.curbuffer[
94 _GREY_MULUQ(dst_stride, vp->y - _grey_info.cb_y + y) +
95 vp->x - _grey_info.cb_x + x]);
96 }
77} 97}
78 98
79/* Draw a line */ 99/* Draw a line */
80void grey_drawline(int x1, int y1, int x2, int y2) 100void grey_drawline(int x1, int y1, int x2, int y2)
81{ 101{
102 struct viewport *vp = _grey_info.vp;
82 int numpixels; 103 int numpixels;
83 int i; 104 int i;
84 int deltax, deltay; 105 int deltax, deltay;
85 int d, dinc1, dinc2; 106 int d, dinc1, dinc2;
86 int x, xinc1, xinc2; 107 int x, xinc1, xinc2;
87 int y, yinc1, yinc2; 108 int y, yinc1, yinc2;
88 void (*pfunc)(unsigned char *address) = _grey_pixelfuncs[_grey_info.drawmode]; 109 void (*pfunc)(unsigned char *address) = _grey_pixelfuncs[vp->drawmode];
110 int dwidth;
111 int xoffs, yoffs;
89 112
90 deltax = abs(x2 - x1); 113 deltax = abs(x2 - x1);
91 deltay = abs(y2 - y1); 114 deltay = abs(y2 - y1);
@@ -127,11 +150,18 @@ void grey_drawline(int x1, int y1, int x2, int y2)
127 x = x1; 150 x = x1;
128 y = y1; 151 y = y1;
129 152
153 dwidth = _grey_info.cb_width;
154 xoffs = vp->x - _grey_info.cb_x;
155 yoffs = vp->y - _grey_info.cb_y;
156
130 for (i = 0; i < numpixels; i++) 157 for (i = 0; i < numpixels; i++)
131 { 158 {
132 if (((unsigned)x < (unsigned)_grey_info.width) 159 if (x >= _grey_info.clip_l && x < _grey_info.clip_r &&
133 && ((unsigned)y < (unsigned)_grey_info.height)) 160 y >= _grey_info.clip_t && y < _grey_info.clip_b)
134 pfunc(&_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]); 161 {
162 pfunc(&_grey_info.curbuffer[_GREY_MULUQ(dwidth, yoffs + y) +
163 xoffs + x]);
164 }
135 165
136 if (d < 0) 166 if (d < 0)
137 { 167 {
@@ -151,10 +181,12 @@ void grey_drawline(int x1, int y1, int x2, int y2)
151/* Draw a horizontal line (optimised) */ 181/* Draw a horizontal line (optimised) */
152void grey_hline(int x1, int x2, int y) 182void grey_hline(int x1, int x2, int y)
153{ 183{
184 struct viewport *vp = _grey_info.vp;
154 int x; 185 int x;
155 int value = 0; 186 int value = 0;
156 unsigned char *dst; 187 unsigned char *dst;
157 bool fillopt = false; 188 bool fillopt = false;
189 int dwidth;
158 190
159 /* direction flip */ 191 /* direction flip */
160 if (x2 < x1) 192 if (x2 < x1)
@@ -165,37 +197,40 @@ void grey_hline(int x1, int x2, int y)
165 } 197 }
166 198
167 /* nothing to draw? */ 199 /* nothing to draw? */
168 if (((unsigned)y >= (unsigned)_grey_info.height) 200 if (y < _grey_info.clip_t || y >= _grey_info.clip_b ||
169 || (x1 >= _grey_info.width) || (x2 < 0)) 201 x1 >= _grey_info.clip_r || x2 < _grey_info.clip_l)
170 return; 202 return;
171 203
172 /* drawmode and optimisation */ 204 /* drawmode and optimisation */
173 if (_grey_info.drawmode & DRMODE_INVERSEVID) 205 if (vp->drawmode & DRMODE_INVERSEVID)
174 { 206 {
175 if (_grey_info.drawmode & DRMODE_BG) 207 if (vp->drawmode & DRMODE_BG)
176 { 208 {
177 fillopt = true; 209 fillopt = true;
178 value = _grey_info.bg_brightness; 210 value = _GREY_BG_BRIGHTNESS(vp);
179 } 211 }
180 } 212 }
181 else 213 else
182 { 214 {
183 if (_grey_info.drawmode & DRMODE_FG) 215 if (vp->drawmode & DRMODE_FG)
184 { 216 {
185 fillopt = true; 217 fillopt = true;
186 value = _grey_info.fg_brightness; 218 value = _GREY_FG_BRIGHTNESS(vp);
187 } 219 }
188 } 220 }
189 if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT) 221 if (!fillopt && vp->drawmode != DRMODE_COMPLEMENT)
190 return; 222 return;
191 223
192 /* clipping */ 224 /* clipping */
193 if (x1 < 0) 225 if (x1 < _grey_info.clip_l)
194 x1 = 0; 226 x1 = _grey_info.clip_l;
195 if (x2 >= _grey_info.width) 227 if (x2 >= _grey_info.clip_r)
196 x2 = _grey_info.width - 1; 228 x2 = _grey_info.clip_r - 1;
197 229
198 dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1]; 230 dwidth = _grey_info.cb_width;
231 dst = &_grey_info.curbuffer[
232 _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y) +
233 vp->x - _grey_info.cb_x + x1];
199 234
200 if (fillopt) 235 if (fillopt)
201 rb->memset(dst, value, x2 - x1 + 1); 236 rb->memset(dst, value, x2 - x1 + 1);
@@ -211,9 +246,11 @@ void grey_hline(int x1, int x2, int y)
211/* Draw a vertical line (optimised) */ 246/* Draw a vertical line (optimised) */
212void grey_vline(int x, int y1, int y2) 247void grey_vline(int x, int y1, int y2)
213{ 248{
249 struct viewport *vp = _grey_info.vp;
214 int y; 250 int y;
215 unsigned char *dst, *dst_end; 251 unsigned char *dst, *dst_end;
216 void (*pfunc)(unsigned char *address); 252 void (*pfunc)(unsigned char *address);
253 int dwidth;
217 254
218 /* direction flip */ 255 /* direction flip */
219 if (y2 < y1) 256 if (y2 < y1)
@@ -224,24 +261,27 @@ void grey_vline(int x, int y1, int y2)
224 } 261 }
225 262
226 /* nothing to draw? */ 263 /* nothing to draw? */
227 if (((unsigned)x >= (unsigned)_grey_info.width) 264 if (x < _grey_info.clip_l || x >= _grey_info.clip_r ||
228 || (y1 >= _grey_info.height) || (y2 < 0)) 265 y1 >= _grey_info.clip_b || y2 < _grey_info.clip_t)
229 return; 266 return;
230 267
231 /* clipping */ 268 /* clipping */
232 if (y1 < 0) 269 if (y1 < _grey_info.clip_t)
233 y1 = 0; 270 y1 = _grey_info.clip_t;
234 if (y2 >= _grey_info.height) 271 if (y2 >= _grey_info.clip_b)
235 y2 = _grey_info.height - 1; 272 y2 = _grey_info.clip_b - 1;
236 273
237 pfunc = _grey_pixelfuncs[_grey_info.drawmode]; 274 dwidth = _grey_info.cb_width;
238 dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y1) + x]; 275 pfunc = _grey_pixelfuncs[vp->drawmode];
239 276 dst = &_grey_info.curbuffer[
240 dst_end = dst + _GREY_MULUQ(_grey_info.width, y2 - y1); 277 _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y1) +
278 vp->x - _grey_info.cb_x + x];
279
280 dst_end = dst + _GREY_MULUQ(dwidth, y2 - y1);
241 do 281 do
242 { 282 {
243 pfunc(dst); 283 pfunc(dst);
244 dst += _grey_info.width; 284 dst += dwidth;
245 } 285 }
246 while (dst <= dst_end); 286 while (dst <= dst_end);
247} 287}
@@ -334,53 +374,63 @@ void grey_drawrect(int x, int y, int width, int height)
334/* Fill a rectangular area */ 374/* Fill a rectangular area */
335void grey_fillrect(int x, int y, int width, int height) 375void grey_fillrect(int x, int y, int width, int height)
336{ 376{
377 struct viewport *vp = _grey_info.vp;
337 int value = 0; 378 int value = 0;
338 unsigned char *dst, *dst_end; 379 unsigned char *dst, *dst_end;
339 bool fillopt = false; 380 bool fillopt = false;
340 381 int dwidth;
341 /* nothing to draw? */
342 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
343 || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
344 return;
345 382
346 /* drawmode and optimisation */ 383 /* drawmode and optimisation */
347 if (_grey_info.drawmode & DRMODE_INVERSEVID) 384 if (vp->drawmode & DRMODE_INVERSEVID)
348 { 385 {
349 if (_grey_info.drawmode & DRMODE_BG) 386 if (vp->drawmode & DRMODE_BG)
350 { 387 {
351 fillopt = true; 388 fillopt = true;
352 value = _grey_info.bg_brightness; 389 value = _GREY_BG_BRIGHTNESS(vp);
353 } 390 }
354 } 391 }
355 else 392 else
356 { 393 {
357 if (_grey_info.drawmode & DRMODE_FG) 394 if (vp->drawmode & DRMODE_FG)
358 { 395 {
359 fillopt = true; 396 fillopt = true;
360 value = _grey_info.fg_brightness; 397 value = _GREY_FG_BRIGHTNESS(vp);
398
361 } 399 }
362 } 400 }
363 if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT) 401 if (!fillopt && vp->drawmode != DRMODE_COMPLEMENT)
364 return; 402 return;
365 403
366 /* clipping */ 404 /* clipping */
367 if (x < 0) 405 if (x < _grey_info.clip_l)
368 { 406 {
369 width += x; 407 width += x - _grey_info.clip_l;
370 x = 0; 408 x = _grey_info.clip_l;
371 } 409 }
372 if (y < 0) 410
411 if (x + width > _grey_info.clip_r)
412 width = _grey_info.clip_r - x;
413
414 if (width <= 0)
415 return;
416
417 if (y < _grey_info.clip_t)
373 { 418 {
374 height += y; 419 height += y - _grey_info.clip_t;
375 y = 0; 420 y = _grey_info.clip_t;
376 } 421 }
377 if (x + width > _grey_info.width) 422
378 width = _grey_info.width - x; 423 if (y + height > _grey_info.clip_b)
379 if (y + height > _grey_info.height) 424 height = _grey_info.clip_b - y;
380 height = _grey_info.height - y; 425
426 if (height <= 0)
427 return;
381 428
382 dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; 429 dwidth = _grey_info.cb_width;
383 dst_end = dst + _GREY_MULUQ(_grey_info.width, height); 430 dst = &_grey_info.curbuffer[
431 _GREY_MULUQ(dwidth, _grey_info.vp->y - _grey_info.cb_y + y) +
432 _grey_info.vp->x - _grey_info.cb_x + x];
433 dst_end = dst + _GREY_MULUQ(dwidth, height);
384 434
385 do 435 do
386 { 436 {
@@ -395,7 +445,7 @@ void grey_fillrect(int x, int y, int width, int height)
395 *dst_row = ~(*dst_row); 445 *dst_row = ~(*dst_row);
396 while (++dst_row < row_end); 446 while (++dst_row < row_end);
397 } 447 }
398 dst += _grey_info.width; 448 dst += dwidth;
399 } 449 }
400 while (dst < dst_end); 450 while (dst < dst_end);
401} 451}
@@ -413,40 +463,49 @@ void grey_fillrect(int x, int y, int width, int height)
413void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, 463void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
414 int stride, int x, int y, int width, int height) 464 int stride, int x, int y, int width, int height)
415{ 465{
466 struct viewport *vp = _grey_info.vp;
416 const unsigned char *src_end; 467 const unsigned char *src_end;
417 unsigned char *dst, *dst_end; 468 unsigned char *dst, *dst_end;
418 unsigned dmask = 0x100; /* bit 8 == sentinel */ 469 unsigned dmask = 0x100; /* bit 8 == sentinel */
419 int drmode = _grey_info.drawmode; 470 int drmode = vp->drawmode;
420 int dwidth; 471 int dwidth;
421 472
422 /* nothing to draw? */
423 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
424 || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
425 return;
426
427 /* clipping */ 473 /* clipping */
428 if (x < 0) 474 if (x < _grey_info.clip_l)
429 { 475 {
430 width += x; 476 int dx = x - _grey_info.clip_l;
431 src_x -= x; 477 width += dx;
432 x = 0; 478 src_x -= dx;
479 x = _grey_info.clip_l;
433 } 480 }
434 if (y < 0) 481
482 if (x + width > _grey_info.clip_r)
483 width = _grey_info.clip_r - x;
484
485 if (width <= 0)
486 return;
487
488 if (y < _grey_info.clip_t)
435 { 489 {
436 height += y; 490 int dy = y - _grey_info.clip_t;
437 src_y -= y; 491 height += dy;
438 y = 0; 492 src_y += dy;
493 y = _grey_info.clip_t;
439 } 494 }
440 if (x + width > _grey_info.width) 495
441 width = _grey_info.width - x; 496 if (y + height > _grey_info.clip_b)
442 if (y + height > _grey_info.height) 497 height = _grey_info.clip_b - y;
443 height = _grey_info.height - y; 498
499 if (height <= 0)
500 return;
444 501
445 src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */ 502 src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */
446 src_y &= 7; 503 src_y &= 7;
447 src_end = src + width; 504 src_end = src + width;
448 dwidth = _grey_info.width; 505 dwidth = _grey_info.cb_width;
449 dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x]; 506 dst = &_grey_info.curbuffer[
507 _GREY_MULUQ(dwidth, vp->y - _grey_info.cb_y + y) +
508 vp->x - _grey_info.cb_x + x];
450 dst_end = dst + _GREY_MULUQ(dwidth, height); 509 dst_end = dst + _GREY_MULUQ(dwidth, height);
451 510
452 if (drmode & DRMODE_INVERSEVID) 511 if (drmode & DRMODE_INVERSEVID)
@@ -485,7 +544,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
485 break; 544 break;
486 545
487 case DRMODE_BG: 546 case DRMODE_BG:
488 bg = _grey_info.bg_brightness; 547 bg = _GREY_BG_BRIGHTNESS(vp);
489 do 548 do
490 { 549 {
491 if (!(data & 0x01)) 550 if (!(data & 0x01))
@@ -498,7 +557,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
498 break; 557 break;
499 558
500 case DRMODE_FG: 559 case DRMODE_FG:
501 fg = _grey_info.fg_brightness; 560 fg = _GREY_FG_BRIGHTNESS(vp);
502 do 561 do
503 { 562 {
504 if (data & 0x01) 563 if (data & 0x01)
@@ -511,8 +570,8 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
511 break; 570 break;
512 571
513 case DRMODE_SOLID: 572 case DRMODE_SOLID:
514 fg = _grey_info.fg_brightness; 573 fg = _GREY_FG_BRIGHTNESS(vp);
515 bg = _grey_info.bg_brightness; 574 bg = _GREY_BG_BRIGHTNESS(vp);
516 do 575 do
517 { 576 {
518 *dst_col = (data & 0x01) ? fg : bg; 577 *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,
537 int stride, int x, int y, int width, int height) 596 int stride, int x, int y, int width, int height)
538{ 597{
539 unsigned char *dst, *dst_end; 598 unsigned char *dst, *dst_end;
540 599 int dwidth;
541 /* nothing to draw? */
542 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
543 || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0))
544 return;
545 600
546 /* clipping */ 601 /* clipping */
547 if (x < 0) 602 if (x < _grey_info.clip_l)
548 { 603 {
549 width += x; 604 int dx = x - _grey_info.clip_l;
550 src_x -= x; 605 width += dx;
551 x = 0; 606 src_x -= dx;
607 x = _grey_info.clip_l;
552 } 608 }
609
610 if (x + width > _grey_info.clip_r)
611 width = _grey_info.clip_r - x;
612
613 if (width <= 0)
614 return;
615
553 if (y < 0) 616 if (y < 0)
554 { 617 {
555 height += y; 618 int dy = y - _grey_info.clip_t;
556 src_y -= y; 619 height += dy;
557 y = 0; 620 src_y -= dy;
621 y = _grey_info.clip_t;
558 } 622 }
559 if (x + width > _grey_info.width)
560 width = _grey_info.width - x;
561 if (y + height > _grey_info.height)
562 height = _grey_info.height - y;
563 623
564 src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ 624 if (y + height > _grey_info.clip_b)
565 dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; 625 height = _grey_info.clip_b - y;
566 dst_end = dst + _GREY_MULUQ(_grey_info.width, height); 626
627 if (height <= 0)
628 return;
629
630 dwidth = _grey_info.cb_width;
631 src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */
632 dst = &_grey_info.curbuffer[
633 _GREY_MULUQ(dwidth, _grey_info.vp->y - _grey_info.cb_y + y) +
634 _grey_info.vp->x - _grey_info.cb_x + x];
635 dst_end = dst + _GREY_MULUQ(dwidth, height);
567 636
568 do 637 do
569 { 638 {
570 rb->memcpy(dst, src, width); 639 rb->memcpy(dst, src, width);
571 dst += _grey_info.width; 640 dst += dwidth;
572 src += stride; 641 src += stride;
573 } 642 }
574 while (dst < dst_end); 643 while (dst < dst_end);
@@ -586,11 +655,15 @@ void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str)
586{ 655{
587 int ch; 656 int ch;
588 unsigned short *ucs; 657 unsigned short *ucs;
589 struct font* pf = rb->font_get(_grey_info.curfont); 658 struct font* pf;
590 659
660 if (_grey_info.clip_b <= _grey_info.clip_t)
661 return;
662
663 pf = rb->font_get(_grey_info.vp->font);
591 ucs = rb->bidi_l2v(str, 1); 664 ucs = rb->bidi_l2v(str, 1);
592 665
593 while ((ch = *ucs++) != 0 && x < _grey_info.width) 666 while ((ch = *ucs++) != 0 && x < _grey_info.clip_r)
594 { 667 {
595 int width; 668 int width;
596 const unsigned char *bits; 669 const unsigned char *bits;
@@ -624,9 +697,10 @@ void grey_putsxy(int x, int y, const unsigned char *str)
624/* Clear the greyscale display (sets all pixels to white) */ 697/* Clear the greyscale display (sets all pixels to white) */
625void grey_ub_clear_display(void) 698void grey_ub_clear_display(void)
626{ 699{
627 int value = _grey_info.gvalue[(_grey_info.drawmode & DRMODE_INVERSEVID) ? 700 struct viewport *vp = &_grey_default_vp;
628 _grey_info.fg_brightness : 701 int value = _grey_info.gvalue[(vp->drawmode & DRMODE_INVERSEVID) ?
629 _grey_info.bg_brightness]; 702 _GREY_FG_BRIGHTNESS(vp) :
703 _GREY_BG_BRIGHTNESS(vp)];
630 704
631 rb->memset(_grey_info.values, value, 705 rb->memset(_grey_info.values, value,
632 _GREY_MULUQ(_grey_info.width, _grey_info.height)); 706 _GREY_MULUQ(_grey_info.width, _grey_info.height));