diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-06-24 22:33:21 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-06-24 22:33:21 +0000 |
commit | 04daef17a1d180c68888c29d11a1b9087e9ace32 (patch) | |
tree | f2d794c196981fc605880e3bbb4447edbaba5f50 /firmware/drivers/lcd-recorder.c | |
parent | 0e935bdf01aff1e3bc66221c9a0fcc80f935c3d6 (diff) | |
download | rockbox-04daef17a1d180c68888c29d11a1b9087e9ace32.tar.gz rockbox-04daef17a1d180c68888c29d11a1b9087e9ace32.zip |
First part of graphics api rework. Special functions, parameter handling, pixel functions, lines and filled primitives done for black & white core, main display.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6856 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/lcd-recorder.c')
-rw-r--r-- | firmware/drivers/lcd-recorder.c | 374 |
1 files changed, 238 insertions, 136 deletions
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c index 52455a1ff5..16a47f28bf 100644 --- a/firmware/drivers/lcd-recorder.c +++ b/firmware/drivers/lcd-recorder.c | |||
@@ -77,6 +77,7 @@ | |||
77 | 77 | ||
78 | unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; | 78 | unsigned char lcd_framebuffer[LCD_HEIGHT/8][LCD_WIDTH]; |
79 | 79 | ||
80 | static int drawmode = DRMODE_SOLID; | ||
80 | static int xmargin = 0; | 81 | static int xmargin = 0; |
81 | static int ymargin = 0; | 82 | static int ymargin = 0; |
82 | static int curfont = FONT_SYSFIXED; | 83 | static int curfont = FONT_SYSFIXED; |
@@ -84,11 +85,6 @@ static int curfont = FONT_SYSFIXED; | |||
84 | static int xoffset; /* needed for flip */ | 85 | static int xoffset; /* needed for flip */ |
85 | #endif | 86 | #endif |
86 | 87 | ||
87 | /* All zeros and ones bitmaps for area filling */ | ||
88 | static const unsigned char zeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
89 | static const unsigned char ones[8] = { 0xff, 0xff, 0xff, 0xff, | ||
90 | 0xff, 0xff, 0xff, 0xff}; | ||
91 | |||
92 | /* scrolling */ | 88 | /* scrolling */ |
93 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ | 89 | static volatile int scrolling_lines=0; /* Bitpattern of which lines are scrolling */ |
94 | static void scroll_thread(void); | 90 | static void scroll_thread(void); |
@@ -335,6 +331,16 @@ void lcd_update_rect(int x_start, int y, int width, int height) | |||
335 | 331 | ||
336 | /*** parameter handling ***/ | 332 | /*** parameter handling ***/ |
337 | 333 | ||
334 | void lcd_set_drawmode(int mode) | ||
335 | { | ||
336 | drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); | ||
337 | } | ||
338 | |||
339 | int lcd_get_drawmode(void) | ||
340 | { | ||
341 | return drawmode; | ||
342 | } | ||
343 | |||
338 | void lcd_setmargins(int x, int y) | 344 | void lcd_setmargins(int x, int y) |
339 | { | 345 | { |
340 | xmargin = x; | 346 | xmargin = x; |
@@ -361,103 +367,75 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) | |||
361 | return font_getstringsize(str, w, h, curfont); | 367 | return font_getstringsize(str, w, h, curfont); |
362 | } | 368 | } |
363 | 369 | ||
364 | /*** drawing functions ***/ | 370 | /*** low-level drawing functions ***/ |
365 | 371 | ||
366 | void lcd_clear_display(void) | 372 | static void setpixel(int x, int y) |
367 | { | 373 | { |
368 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); | 374 | lcd_framebuffer[y/8][x] |= 1 << (y & 7); |
369 | scrolling_lines = 0; | ||
370 | } | 375 | } |
371 | 376 | ||
372 | /* Set a single pixel */ | 377 | static void clearpixel(int x, int y) |
373 | void lcd_drawpixel(int x, int y) | ||
374 | { | 378 | { |
375 | DRAW_PIXEL(x,y); | 379 | lcd_framebuffer[y/8][x] &= ~(1 << (y & 7)); |
376 | } | 380 | } |
377 | 381 | ||
378 | /* Clear a single pixel */ | 382 | static void flippixel(int x, int y) |
379 | void lcd_clearpixel(int x, int y) | ||
380 | { | 383 | { |
381 | CLEAR_PIXEL(x,y); | 384 | lcd_framebuffer[y/8][x] ^= 1 << (y & 7); |
382 | } | 385 | } |
383 | 386 | ||
384 | /* Invert a single pixel */ | 387 | static void nopixel(int x, int y) |
385 | void lcd_invertpixel(int x, int y) | ||
386 | { | 388 | { |
387 | INVERT_PIXEL(x,y); | 389 | (void)x; |
390 | (void)y; | ||
388 | } | 391 | } |
389 | 392 | ||
390 | void lcd_drawline(int x1, int y1, int x2, int y2) | 393 | tLCDPixelFunc* pixelfunc[8] = {flippixel, nopixel, setpixel, setpixel, |
394 | nopixel, clearpixel, nopixel, clearpixel}; | ||
395 | |||
396 | static void flipblock(unsigned char *address, unsigned mask, unsigned bits) | ||
391 | { | 397 | { |
392 | int numpixels; | 398 | *address ^= (bits & mask); |
393 | int i; | 399 | } |
394 | int deltax, deltay; | ||
395 | int d, dinc1, dinc2; | ||
396 | int x, xinc1, xinc2; | ||
397 | int y, yinc1, yinc2; | ||
398 | 400 | ||
399 | deltax = abs(x2 - x1); | 401 | static void bgblock(unsigned char *address, unsigned mask, unsigned bits) |
400 | deltay = abs(y2 - y1); | 402 | { |
403 | *address &= (bits | ~mask); | ||
404 | } | ||
401 | 405 | ||
402 | if(deltax >= deltay) | 406 | static void fgblock(unsigned char *address, unsigned mask, unsigned bits) |
403 | { | 407 | { |
404 | numpixels = deltax; | 408 | *address |= (bits & mask); |
405 | d = 2 * deltay - deltax; | 409 | } |
406 | dinc1 = deltay * 2; | ||
407 | dinc2 = (deltay - deltax) * 2; | ||
408 | xinc1 = 1; | ||
409 | xinc2 = 1; | ||
410 | yinc1 = 0; | ||
411 | yinc2 = 1; | ||
412 | } | ||
413 | else | ||
414 | { | ||
415 | numpixels = deltay; | ||
416 | d = 2 * deltax - deltay; | ||
417 | dinc1 = deltax * 2; | ||
418 | dinc2 = (deltax - deltay) * 2; | ||
419 | xinc1 = 0; | ||
420 | xinc2 = 1; | ||
421 | yinc1 = 1; | ||
422 | yinc2 = 1; | ||
423 | } | ||
424 | numpixels++; /* include endpoints */ | ||
425 | 410 | ||
426 | if(x1 > x2) | 411 | static void solidblock(unsigned char *address, unsigned mask, unsigned bits) |
427 | { | 412 | { |
428 | xinc1 = -xinc1; | 413 | *address = (*address & ~mask) | (bits & mask); |
429 | xinc2 = -xinc2; | 414 | } |
430 | } | ||
431 | 415 | ||
432 | if(y1 > y2) | 416 | tLCDBlockFunc* blockfunc[4] = {flipblock, bgblock, fgblock, solidblock}; |
433 | { | ||
434 | yinc1 = -yinc1; | ||
435 | yinc2 = -yinc2; | ||
436 | } | ||
437 | 417 | ||
438 | x = x1; | 418 | /*** drawing functions ***/ |
439 | y = y1; | ||
440 | 419 | ||
441 | for(i=0; i<numpixels; i++) | 420 | /* Clear the whole display */ |
442 | { | 421 | void lcd_clear_display(void) |
443 | DRAW_PIXEL(x,y); | 422 | { |
423 | if (drawmode & DRMODE_INVERSEVID) | ||
424 | memset (lcd_framebuffer, 0xFF, sizeof lcd_framebuffer); | ||
425 | else | ||
426 | memset (lcd_framebuffer, 0, sizeof lcd_framebuffer); | ||
427 | scrolling_lines = 0; | ||
428 | } | ||
444 | 429 | ||
445 | if(d < 0) | 430 | /* Set a single pixel */ |
446 | { | 431 | void lcd_drawpixel(int x, int y) |
447 | d += dinc1; | 432 | { |
448 | x += xinc1; | 433 | if (((unsigned)x < LCD_WIDTH) || ((unsigned)y < LCD_HEIGHT)) |
449 | y += yinc1; | 434 | pixelfunc[drawmode](x, y); |
450 | } | ||
451 | else | ||
452 | { | ||
453 | d += dinc2; | ||
454 | x += xinc2; | ||
455 | y += yinc2; | ||
456 | } | ||
457 | } | ||
458 | } | 435 | } |
459 | 436 | ||
460 | void lcd_clearline(int x1, int y1, int x2, int y2) | 437 | /* Draw a line */ |
438 | void lcd_drawline(int x1, int y1, int x2, int y2) | ||
461 | { | 439 | { |
462 | int numpixels; | 440 | int numpixels; |
463 | int i; | 441 | int i; |
@@ -465,20 +443,21 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
465 | int d, dinc1, dinc2; | 443 | int d, dinc1, dinc2; |
466 | int x, xinc1, xinc2; | 444 | int x, xinc1, xinc2; |
467 | int y, yinc1, yinc2; | 445 | int y, yinc1, yinc2; |
446 | tLCDPixelFunc *pfunc = pixelfunc[drawmode]; | ||
468 | 447 | ||
469 | deltax = abs(x2 - x1); | 448 | deltax = abs(x2 - x1); |
470 | deltay = abs(y2 - y1); | 449 | deltay = abs(y2 - y1); |
450 | xinc2 = 1; | ||
451 | yinc2 = 1; | ||
471 | 452 | ||
472 | if(deltax >= deltay) | 453 | if (deltax >= deltay) |
473 | { | 454 | { |
474 | numpixels = deltax; | 455 | numpixels = deltax; |
475 | d = 2 * deltay - deltax; | 456 | d = 2 * deltay - deltax; |
476 | dinc1 = deltay * 2; | 457 | dinc1 = deltay * 2; |
477 | dinc2 = (deltay - deltax) * 2; | 458 | dinc2 = (deltay - deltax) * 2; |
478 | xinc1 = 1; | 459 | xinc1 = 1; |
479 | xinc2 = 1; | ||
480 | yinc1 = 0; | 460 | yinc1 = 0; |
481 | yinc2 = 1; | ||
482 | } | 461 | } |
483 | else | 462 | else |
484 | { | 463 | { |
@@ -487,19 +466,17 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
487 | dinc1 = deltax * 2; | 466 | dinc1 = deltax * 2; |
488 | dinc2 = (deltax - deltay) * 2; | 467 | dinc2 = (deltax - deltay) * 2; |
489 | xinc1 = 0; | 468 | xinc1 = 0; |
490 | xinc2 = 1; | ||
491 | yinc1 = 1; | 469 | yinc1 = 1; |
492 | yinc2 = 1; | ||
493 | } | 470 | } |
494 | numpixels++; /* include endpoints */ | 471 | numpixels++; /* include endpoints */ |
495 | 472 | ||
496 | if(x1 > x2) | 473 | if (x1 > x2) |
497 | { | 474 | { |
498 | xinc1 = -xinc1; | 475 | xinc1 = -xinc1; |
499 | xinc2 = -xinc2; | 476 | xinc2 = -xinc2; |
500 | } | 477 | } |
501 | 478 | ||
502 | if(y1 > y2) | 479 | if (y1 > y2) |
503 | { | 480 | { |
504 | yinc1 = -yinc1; | 481 | yinc1 = -yinc1; |
505 | yinc2 = -yinc2; | 482 | yinc2 = -yinc2; |
@@ -508,11 +485,12 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
508 | x = x1; | 485 | x = x1; |
509 | y = y1; | 486 | y = y1; |
510 | 487 | ||
511 | for(i=0; i<numpixels; i++) | 488 | for (i = 0; i < numpixels; i++) |
512 | { | 489 | { |
513 | CLEAR_PIXEL(x,y); | 490 | if (((unsigned)x < LCD_WIDTH) && ((unsigned)y < LCD_HEIGHT)) |
491 | pfunc(x, y); | ||
514 | 492 | ||
515 | if(d < 0) | 493 | if (d < 0) |
516 | { | 494 | { |
517 | d += dinc1; | 495 | d += dinc1; |
518 | x += xinc1; | 496 | x += xinc1; |
@@ -527,68 +505,178 @@ void lcd_clearline(int x1, int y1, int x2, int y2) | |||
527 | } | 505 | } |
528 | } | 506 | } |
529 | 507 | ||
530 | /* Draw a rectangle with upper left corner at (x, y) and size (nx, ny) */ | 508 | /* Draw a horizontal line (optimised) */ |
531 | void lcd_drawrect(int x, int y, int nx, int ny) | 509 | void lcd_hline(int x1, int x2, int y) |
532 | { | 510 | { |
533 | int i; | 511 | int x; |
512 | unsigned char *dst; | ||
513 | unsigned char mask, bits; | ||
514 | tLCDBlockFunc *bfunc; | ||
534 | 515 | ||
535 | if (x > LCD_WIDTH) | 516 | /* direction flip */ |
536 | return; | 517 | if (x2 < x1) |
537 | if (y > LCD_HEIGHT) | 518 | { |
538 | return; | 519 | x = x1; |
520 | x1 = x2; | ||
521 | x2 = x; | ||
522 | } | ||
523 | |||
524 | /* nothing to draw? */ | ||
525 | if (((unsigned)y >= LCD_HEIGHT) || (x1 >= LCD_WIDTH) || (x2 < 0)) | ||
526 | return; | ||
527 | |||
528 | /* clipping */ | ||
529 | if (x1 < 0) | ||
530 | x1 = 0; | ||
531 | if (x2 >= LCD_WIDTH) | ||
532 | x2 = LCD_WIDTH-1; | ||
533 | |||
534 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
535 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
536 | dst = &lcd_framebuffer[y/8][x1]; | ||
537 | mask = 1 << (y & 7); | ||
539 | 538 | ||
540 | if (x + nx > LCD_WIDTH) | 539 | for (x = x1; x <= x2; x++) |
541 | nx = LCD_WIDTH - x; | 540 | bfunc(dst++, mask, bits); |
542 | if (y + ny > LCD_HEIGHT) | 541 | } |
543 | ny = LCD_HEIGHT - y; | 542 | |
543 | /* Draw a vertical line (optimised) */ | ||
544 | void lcd_vline(int x, int y1, int y2) | ||
545 | { | ||
546 | int ny; | ||
547 | unsigned char *dst; | ||
548 | unsigned char mask_top, mask_bottom, bits; | ||
549 | tLCDBlockFunc *bfunc; | ||
544 | 550 | ||
545 | /* vertical lines */ | 551 | /* direction flip */ |
546 | for (i = 0; i < ny; i++) { | 552 | if (y2 < y1) |
547 | DRAW_PIXEL(x, (y + i)); | 553 | { |
548 | DRAW_PIXEL((x + nx - 1), (y + i)); | 554 | ny = y1; |
555 | y1 = y2; | ||
556 | y2 = ny; | ||
549 | } | 557 | } |
550 | 558 | ||
551 | /* horizontal lines */ | 559 | /* nothing to draw? */ |
552 | for (i = 0; i < nx; i++) { | 560 | if (((unsigned)x >= LCD_WIDTH) || (y1 >= LCD_HEIGHT) || (y2 < 0)) |
553 | DRAW_PIXEL((x + i),y); | 561 | return; |
554 | DRAW_PIXEL((x + i),(y + ny - 1)); | 562 | |
563 | /* clipping */ | ||
564 | if (y1 < 0) | ||
565 | y1 = 0; | ||
566 | if (y2 >= LCD_HEIGHT) | ||
567 | y2 = LCD_HEIGHT-1; | ||
568 | |||
569 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
570 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
571 | dst = &lcd_framebuffer[y1/8][x]; | ||
572 | ny = y2 - (y1 & ~7); | ||
573 | mask_top = 0xFFu << (y1 & 7); | ||
574 | mask_bottom = 0xFFu >> (7 - (ny & 7)); | ||
575 | |||
576 | if (ny >= 8) | ||
577 | { | ||
578 | bfunc(dst, mask_top, bits); | ||
579 | dst += LCD_WIDTH; | ||
580 | |||
581 | for (; ny > 15; ny -= 8) | ||
582 | { | ||
583 | bfunc(dst, 0xFFu, bits); | ||
584 | dst += LCD_WIDTH; | ||
585 | } | ||
555 | } | 586 | } |
587 | else | ||
588 | mask_bottom &= mask_top; | ||
589 | |||
590 | bfunc(dst, mask_bottom, bits); | ||
556 | } | 591 | } |
557 | 592 | ||
558 | /* Clear a rectangular area at (x, y), size (nx, ny) */ | 593 | /* Draw a rectangular box */ |
559 | void lcd_clearrect(int x, int y, int nx, int ny) | 594 | void lcd_drawrect(int x, int y, int width, int height) |
560 | { | 595 | { |
561 | int i; | 596 | if ((width <= 0) || (height <= 0)) |
562 | for (i = 0; i < nx; i++) | 597 | return; |
563 | lcd_bitmap(zeros, x+i, y, 1, ny, true); | 598 | |
599 | int x2 = x + width - 1; | ||
600 | int y2 = y + height - 1; | ||
601 | |||
602 | lcd_vline(x, y, y2); | ||
603 | lcd_vline(x2, y, y2); | ||
604 | lcd_hline(x, x2, y); | ||
605 | lcd_hline(x, x2, y2); | ||
564 | } | 606 | } |
565 | 607 | ||
566 | /* Fill a rectangular area at (x, y), size (nx, ny) */ | 608 | /* helper function for lcd_fillrect() */ |
567 | void lcd_fillrect(int x, int y, int nx, int ny) | 609 | static void fillrow(tLCDBlockFunc *bfunc, unsigned char *address, |
610 | int width, unsigned mask, unsigned bits) | ||
568 | { | 611 | { |
569 | int i; | 612 | int i; |
570 | for (i = 0; i < nx; i++) | 613 | |
571 | lcd_bitmap(ones, x+i, y, 1, ny, true); | 614 | for (i = 0; i < width; i++) |
615 | bfunc(address++, mask, bits); | ||
572 | } | 616 | } |
573 | 617 | ||
574 | /* Invert a rectangular area at (x, y), size (nx, ny) */ | 618 | /* Fill a rectangular area */ |
575 | void lcd_invertrect(int x, int y, int nx, int ny) | 619 | void lcd_fillrect(int x, int y, int width, int height) |
576 | { | 620 | { |
577 | int i, j; | 621 | int ny; |
578 | 622 | unsigned char *dst; | |
579 | if (x > LCD_WIDTH) | 623 | unsigned char mask_top, mask_bottom, bits; |
580 | return; | 624 | tLCDBlockFunc *bfunc; |
581 | if (y > LCD_HEIGHT) | 625 | bool fillopt = (drawmode & DRMODE_INVERSEVID) ? |
626 | (drawmode & DRMODE_BG) : (drawmode & DRMODE_FG); | ||
627 | |||
628 | /* nothing to draw? */ | ||
629 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
630 | || (x + width < 0) || (y + height < 0)) | ||
582 | return; | 631 | return; |
583 | 632 | ||
584 | if (x + nx > LCD_WIDTH) | 633 | /* clipping */ |
585 | nx = LCD_WIDTH - x; | 634 | if (x < 0) |
586 | if (y + ny > LCD_HEIGHT) | 635 | { |
587 | ny = LCD_HEIGHT - y; | 636 | width += x; |
588 | 637 | x = 0; | |
589 | for (i = 0; i < nx; i++) | 638 | } |
590 | for (j = 0; j < ny; j++) | 639 | if (y < 0) |
591 | INVERT_PIXEL((x + i), (y + j)); | 640 | { |
641 | height += y; | ||
642 | y = 0; | ||
643 | } | ||
644 | if (x + width > LCD_WIDTH) | ||
645 | width = LCD_WIDTH - x; | ||
646 | if (y + height > LCD_HEIGHT) | ||
647 | height = LCD_HEIGHT - y; | ||
648 | |||
649 | bfunc = blockfunc[drawmode & ~DRMODE_INVERSEVID]; | ||
650 | bits = (drawmode & DRMODE_INVERSEVID) ? 0x00 : 0xFFu; | ||
651 | dst = &lcd_framebuffer[y/8][x]; | ||
652 | ny = height - 1 + (y & 7); | ||
653 | mask_top = 0xFFu << (y & 7); | ||
654 | mask_bottom = 0xFFu >> (7 - (ny & 7)); | ||
655 | |||
656 | if (ny >= 8) | ||
657 | { | ||
658 | if (fillopt && mask_top == 0xFF) | ||
659 | memset(dst, bits, width); | ||
660 | else | ||
661 | fillrow(bfunc, dst, width, mask_top, bits); | ||
662 | dst += LCD_WIDTH; | ||
663 | |||
664 | for (; ny > 15; ny -= 8) | ||
665 | { | ||
666 | if (fillopt) | ||
667 | memset(dst, bits, width); | ||
668 | else | ||
669 | fillrow(bfunc, dst, width, 0xFFu, bits); | ||
670 | dst += LCD_WIDTH; | ||
671 | } | ||
672 | } | ||
673 | else | ||
674 | mask_bottom &= mask_top; | ||
675 | |||
676 | if (fillopt && mask_bottom == 0xFF) | ||
677 | memset(dst, bits, width); | ||
678 | else | ||
679 | fillrow(bfunc, dst, width, mask_bottom, bits); | ||
592 | } | 680 | } |
593 | 681 | ||
594 | /* About Rockbox' internal bitmap format: | 682 | /* About Rockbox' internal bitmap format: |
@@ -756,6 +844,7 @@ void lcd_putsxy(int x, int y, const unsigned char *str) | |||
756 | void lcd_puts_style(int x, int y, const unsigned char *str, int style) | 844 | void lcd_puts_style(int x, int y, const unsigned char *str, int style) |
757 | { | 845 | { |
758 | int xpos,ypos,w,h; | 846 | int xpos,ypos,w,h; |
847 | int lastmode = lcd_get_drawmode(); | ||
759 | 848 | ||
760 | /* make sure scrolling is turned off on the line we are updating */ | 849 | /* make sure scrolling is turned off on the line we are updating */ |
761 | scrolling_lines &= ~(1 << y); | 850 | scrolling_lines &= ~(1 << y); |
@@ -767,9 +856,14 @@ void lcd_puts_style(int x, int y, const unsigned char *str, int style) | |||
767 | xpos = xmargin + x*w / strlen(str); | 856 | xpos = xmargin + x*w / strlen(str); |
768 | ypos = ymargin + y*h; | 857 | ypos = ymargin + y*h; |
769 | lcd_putsxy(xpos, ypos, str); | 858 | lcd_putsxy(xpos, ypos, str); |
770 | lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); | 859 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); |
860 | lcd_fillrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h); | ||
771 | if (style & STYLE_INVERT) | 861 | if (style & STYLE_INVERT) |
772 | lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, h); | 862 | { |
863 | lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
864 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, h); | ||
865 | } | ||
866 | lcd_set_drawmode(lastmode); | ||
773 | } | 867 | } |
774 | 868 | ||
775 | /* put a string at a given char position */ | 869 | /* put a string at a given char position */ |
@@ -885,6 +979,7 @@ static void scroll_thread(void) | |||
885 | struct scrollinfo* s; | 979 | struct scrollinfo* s; |
886 | int index; | 980 | int index; |
887 | int xpos, ypos; | 981 | int xpos, ypos; |
982 | int lastmode; | ||
888 | 983 | ||
889 | /* initialize scroll struct array */ | 984 | /* initialize scroll struct array */ |
890 | scrolling_lines = 0; | 985 | scrolling_lines = 0; |
@@ -930,10 +1025,17 @@ static void scroll_thread(void) | |||
930 | s->offset %= s->width; | 1025 | s->offset %= s->width; |
931 | } | 1026 | } |
932 | 1027 | ||
933 | lcd_clearrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 1028 | lastmode = lcd_get_drawmode(); |
1029 | lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); | ||
1030 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1031 | lcd_set_drawmode(DRMODE_SOLID); | ||
934 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); | 1032 | lcd_putsxyofs(xpos, ypos, s->offset, s->line); |
935 | if (s->invert) | 1033 | if (s->invert) |
936 | lcd_invertrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 1034 | { |
1035 | lcd_set_drawmode(DRMODE_COMPLEMENT); | ||
1036 | lcd_fillrect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | ||
1037 | } | ||
1038 | lcd_set_drawmode(lastmode); | ||
937 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); | 1039 | lcd_update_rect(xpos, ypos, LCD_WIDTH - xpos, pf->height); |
938 | } | 1040 | } |
939 | 1041 | ||