diff options
Diffstat (limited to 'firmware/drivers/lcd-1bit-vert.c')
-rw-r--r-- | firmware/drivers/lcd-1bit-vert.c | 133 |
1 files changed, 123 insertions, 10 deletions
diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 9607f284aa..ae7cddb19a 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c | |||
@@ -66,6 +66,28 @@ void LCDFN(set_viewport)(struct viewport* vp) | |||
66 | current_vp = &default_vp; | 66 | current_vp = &default_vp; |
67 | else | 67 | else |
68 | current_vp = vp; | 68 | current_vp = vp; |
69 | |||
70 | #if defined(SIMULATOR) | ||
71 | /* Force the viewport to be within bounds. If this happens it should | ||
72 | * be considered an error - the viewport will not draw as it might be | ||
73 | * expected. | ||
74 | */ | ||
75 | if((unsigned) current_vp->x > (unsigned) LCDM(WIDTH) | ||
76 | || (unsigned) current_vp->y > (unsigned) LCDM(HEIGHT) | ||
77 | || current_vp->x + current_vp->width > LCDM(WIDTH) | ||
78 | || current_vp->y + current_vp->height > LCDM(HEIGHT)) | ||
79 | { | ||
80 | #if !defined(HAVE_VIEWPORT_CLIP) | ||
81 | DEBUGF("ERROR: " | ||
82 | #else | ||
83 | DEBUGF("NOTE: " | ||
84 | #endif | ||
85 | "set_viewport out of bounds: x: %d y: %d width: %d height:%d\n", | ||
86 | current_vp->x, current_vp->y, | ||
87 | current_vp->width, current_vp->height); | ||
88 | } | ||
89 | |||
90 | #endif | ||
69 | } | 91 | } |
70 | 92 | ||
71 | void LCDFN(update_viewport)(void) | 93 | void LCDFN(update_viewport)(void) |
@@ -254,8 +276,13 @@ void LCDFN(clear_viewport)(void) | |||
254 | /* Set a single pixel */ | 276 | /* Set a single pixel */ |
255 | void LCDFN(drawpixel)(int x, int y) | 277 | void LCDFN(drawpixel)(int x, int y) |
256 | { | 278 | { |
257 | if (((unsigned)x < (unsigned)current_vp->width) && | 279 | if ( ((unsigned)x < (unsigned)current_vp->width) |
258 | ((unsigned)y < (unsigned)current_vp->height)) | 280 | && ((unsigned)y < (unsigned)current_vp->height) |
281 | #if defined(HAVE_VIEWPORT_CLIP) | ||
282 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | ||
283 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | ||
284 | #endif | ||
285 | ) | ||
259 | LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x + x, current_vp->y + y); | 286 | LCDFN(pixelfuncs)[current_vp->drawmode](current_vp->x + x, current_vp->y + y); |
260 | } | 287 | } |
261 | 288 | ||
@@ -324,8 +351,13 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) | |||
324 | 351 | ||
325 | for (i = 0; i < numpixels; i++) | 352 | for (i = 0; i < numpixels; i++) |
326 | { | 353 | { |
327 | if (((unsigned)x < (unsigned)current_vp->width) | 354 | if ( ((unsigned)x < (unsigned)current_vp->width) |
328 | && ((unsigned)y < (unsigned)current_vp->height)) | 355 | && ((unsigned)y < (unsigned)current_vp->height) |
356 | #if defined(HAVE_VIEWPORT_CLIP) | ||
357 | && ((unsigned)x < (unsigned)LCDM(WIDTH)) | ||
358 | && ((unsigned)y < (unsigned)LCDM(HEIGHT)) | ||
359 | #endif | ||
360 | ) | ||
329 | pfunc(current_vp->x + x, current_vp->y + y); | 361 | pfunc(current_vp->x + x, current_vp->y + y); |
330 | 362 | ||
331 | if (d < 0) | 363 | if (d < 0) |
@@ -359,22 +391,38 @@ void LCDFN(hline)(int x1, int x2, int y) | |||
359 | x2 = x; | 391 | x2 = x; |
360 | } | 392 | } |
361 | 393 | ||
394 | /******************** In viewport clipping **********************/ | ||
362 | /* nothing to draw? */ | 395 | /* nothing to draw? */ |
363 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) | 396 | if (((unsigned)y >= (unsigned)current_vp->height) || (x1 >= current_vp->width) |
364 | || (x2 < 0)) | 397 | || (x2 < 0)) |
365 | return; | 398 | return; |
366 | 399 | ||
367 | /* clipping */ | ||
368 | if (x1 < 0) | 400 | if (x1 < 0) |
369 | x1 = 0; | 401 | x1 = 0; |
370 | if (x2 >= current_vp->width) | 402 | if (x2 >= current_vp->width) |
371 | x2 = current_vp->width-1; | 403 | x2 = current_vp->width-1; |
372 | 404 | ||
373 | width = x2 - x1 + 1; | ||
374 | |||
375 | /* adjust to viewport */ | 405 | /* adjust to viewport */ |
376 | x1 += current_vp->x; | 406 | x1 += current_vp->x; |
377 | y += current_vp->y; | 407 | y += current_vp->y; |
408 | |||
409 | #if defined(HAVE_VIEWPORT_CLIP) | ||
410 | x2 += current_vp->x; | ||
411 | |||
412 | /********************* Viewport on screen clipping ********************/ | ||
413 | /* nothing to draw? */ | ||
414 | if (((unsigned)y >= (unsigned) LCDM(HEIGHT)) || (x1 >= LCDM(WIDTH)) | ||
415 | || (x2 < 0)) | ||
416 | return; | ||
417 | |||
418 | /* clipping */ | ||
419 | if (x1 < 0) | ||
420 | x1 = 0; | ||
421 | if (x2 >= LCDM(WIDTH)) | ||
422 | x2 = LCDM(WIDTH)-1; | ||
423 | #endif | ||
424 | |||
425 | width = x2 - x1 + 1; | ||
378 | 426 | ||
379 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 427 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; |
380 | dst = &LCDFN(framebuffer)[y>>3][x1]; | 428 | dst = &LCDFN(framebuffer)[y>>3][x1]; |
@@ -402,12 +450,12 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
402 | y2 = ny; | 450 | y2 = ny; |
403 | } | 451 | } |
404 | 452 | ||
453 | /******************** In viewport clipping **********************/ | ||
405 | /* nothing to draw? */ | 454 | /* nothing to draw? */ |
406 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) | 455 | if (((unsigned)x >= (unsigned)current_vp->width) || (y1 >= current_vp->height) |
407 | || (y2 < 0)) | 456 | || (y2 < 0)) |
408 | return; | 457 | return; |
409 | 458 | ||
410 | /* clipping */ | ||
411 | if (y1 < 0) | 459 | if (y1 < 0) |
412 | y1 = 0; | 460 | y1 = 0; |
413 | if (y2 >= current_vp->height) | 461 | if (y2 >= current_vp->height) |
@@ -417,6 +465,20 @@ void LCDFN(vline)(int x, int y1, int y2) | |||
417 | y1 += current_vp->y; | 465 | y1 += current_vp->y; |
418 | y2 += current_vp->y; | 466 | y2 += current_vp->y; |
419 | x += current_vp->x; | 467 | x += current_vp->x; |
468 | |||
469 | #if defined(HAVE_VIEWPORT_CLIP) | ||
470 | /********************* Viewport on screen clipping ********************/ | ||
471 | /* nothing to draw? */ | ||
472 | if (( (unsigned) x >= (unsigned)LCDM(WIDTH)) || (y1 >= LCDM(HEIGHT)) | ||
473 | || (y2 < 0)) | ||
474 | return; | ||
475 | |||
476 | /* clipping */ | ||
477 | if (y1 < 0) | ||
478 | y1 = 0; | ||
479 | if (y2 >= LCDM(HEIGHT)) | ||
480 | y2 = LCDM(HEIGHT)-1; | ||
481 | #endif | ||
420 | 482 | ||
421 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; | 483 | bfunc = LCDFN(blockfuncs)[current_vp->drawmode]; |
422 | dst = &LCDFN(framebuffer)[y1>>3][x]; | 484 | dst = &LCDFN(framebuffer)[y1>>3][x]; |
@@ -459,12 +521,12 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
459 | LCDFN(blockfunc_type) *bfunc; | 521 | LCDFN(blockfunc_type) *bfunc; |
460 | bool fillopt = false; | 522 | bool fillopt = false; |
461 | 523 | ||
524 | /******************** In viewport clipping **********************/ | ||
462 | /* nothing to draw? */ | 525 | /* nothing to draw? */ |
463 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 526 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
464 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 527 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
465 | return; | 528 | return; |
466 | 529 | ||
467 | /* clipping */ | ||
468 | if (x < 0) | 530 | if (x < 0) |
469 | { | 531 | { |
470 | width += x; | 532 | width += x; |
@@ -483,6 +545,30 @@ void LCDFN(fillrect)(int x, int y, int width, int height) | |||
483 | /* adjust for viewport */ | 545 | /* adjust for viewport */ |
484 | x += current_vp->x; | 546 | x += current_vp->x; |
485 | y += current_vp->y; | 547 | y += current_vp->y; |
548 | |||
549 | #if defined(HAVE_VIEWPORT_CLIP) | ||
550 | /********************* Viewport on screen clipping ********************/ | ||
551 | /* nothing to draw? */ | ||
552 | if ((x >= LCDM(WIDTH)) || (y >= LCDM(HEIGHT)) | ||
553 | || (x + width <= 0) || (y + height <= 0)) | ||
554 | return; | ||
555 | |||
556 | /* clip image in viewport in screen */ | ||
557 | if (x < 0) | ||
558 | { | ||
559 | width += x; | ||
560 | x = 0; | ||
561 | } | ||
562 | if (y < 0) | ||
563 | { | ||
564 | height += y; | ||
565 | y = 0; | ||
566 | } | ||
567 | if (x + width > LCDM(WIDTH)) | ||
568 | width = LCDM(WIDTH) - x; | ||
569 | if (y + height > LCDM(HEIGHT)) | ||
570 | height = LCDM(HEIGHT) - y; | ||
571 | #endif | ||
486 | 572 | ||
487 | if (current_vp->drawmode & DRMODE_INVERSEVID) | 573 | if (current_vp->drawmode & DRMODE_INVERSEVID) |
488 | { | 574 | { |
@@ -556,12 +642,13 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
556 | unsigned mask, mask_bottom; | 642 | unsigned mask, mask_bottom; |
557 | LCDFN(blockfunc_type) *bfunc; | 643 | LCDFN(blockfunc_type) *bfunc; |
558 | 644 | ||
645 | /******************** Image in viewport clipping **********************/ | ||
559 | /* nothing to draw? */ | 646 | /* nothing to draw? */ |
560 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) | 647 | if ((width <= 0) || (height <= 0) || (x >= current_vp->width) |
561 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) | 648 | || (y >= current_vp->height) || (x + width <= 0) || (y + height <= 0)) |
562 | return; | 649 | return; |
563 | 650 | ||
564 | /* clipping */ | 651 | /* clip image in viewport */ |
565 | if (x < 0) | 652 | if (x < 0) |
566 | { | 653 | { |
567 | width += x; | 654 | width += x; |
@@ -582,6 +669,32 @@ void ICODE_ATTR LCDFN(bitmap_part)(const unsigned char *src, int src_x, | |||
582 | /* adjust for viewport */ | 669 | /* adjust for viewport */ |
583 | x += current_vp->x; | 670 | x += current_vp->x; |
584 | y += current_vp->y; | 671 | y += current_vp->y; |
672 | |||
673 | #if defined(HAVE_VIEWPORT_CLIP) | ||
674 | /********************* Viewport on screen clipping ********************/ | ||
675 | /* nothing to draw? */ | ||
676 | if ((x >= LCDM(WIDTH)) || (y >= LCDM(HEIGHT)) | ||
677 | || (x + width <= 0) || (y + height <= 0)) | ||
678 | return; | ||
679 | |||
680 | /* clip image in viewport in screen */ | ||
681 | if (x < 0) | ||
682 | { | ||
683 | width += x; | ||
684 | src_x -= x; | ||
685 | x = 0; | ||
686 | } | ||
687 | if (y < 0) | ||
688 | { | ||
689 | height += y; | ||
690 | src_y -= y; | ||
691 | y = 0; | ||
692 | } | ||
693 | if (x + width > LCDM(WIDTH)) | ||
694 | width = LCDM(WIDTH) - x; | ||
695 | if (y + height > LCDM(HEIGHT)) | ||
696 | height = LCDM(HEIGHT) - y; | ||
697 | #endif | ||
585 | 698 | ||
586 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | 699 | src += stride * (src_y >> 3) + src_x; /* move starting point */ |
587 | src_y &= 7; | 700 | src_y &= 7; |