summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/lcd-recorder.c90
-rw-r--r--firmware/font.c55
2 files changed, 75 insertions, 70 deletions
diff --git a/firmware/drivers/lcd-recorder.c b/firmware/drivers/lcd-recorder.c
index 8cf5f12b8b..c174430c83 100644
--- a/firmware/drivers/lcd-recorder.c
+++ b/firmware/drivers/lcd-recorder.c
@@ -436,15 +436,16 @@ void lcd_putsxy(int x, int y, unsigned char *str)
436} 436}
437 437
438/* 438/*
439 * All bitmaps have this format: 439 * About Rockbox' internal bitmap format:
440 * Bits within a byte are arranged veritcally, LSB at top.
441 * Bytes are stored in column-major format, with byte 0 at top left,
442 * byte 1 is 2nd from top, etc. Bytes following left-most column
443 * starts 2nd left column, etc.
444 * 440 *
445 * Note: The HW takes bitmap bytes in row-major order. 441 * A bitmap contains one bit for every pixel that defines if that pixel is
442 * black (1) or white (0). Bits within a byte are arranged vertically, LSB
443 * at top.
444 * The bytes are stored in row-major order, with byte 0 being top left,
445 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
446 * 0..7, the second row defines pixel row 8..15 etc.
446 * 447 *
447 * Memory copy of display bitmap 448 * This is the same as the internal lcd hw format.
448 */ 449 */
449 450
450/* 451/*
@@ -456,77 +457,88 @@ void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
456void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny, 457void lcd_bitmap (unsigned char *src, int x, int y, int nx, int ny,
457 bool clear) 458 bool clear)
458{ 459{
459 unsigned char *dst; 460 unsigned char *src_col, *dst, *dst_col;
460 unsigned char *dst2; 461 unsigned int data, mask1, mask2, mask3, mask4;
461 unsigned int data, mask, mask2, mask3, mask4; 462 int stride, shift;
462 int shift;
463 463
464 if (((unsigned)x >= LCD_WIDTH) || ((unsigned)y >= LCD_HEIGHT)) 464 if (((unsigned) x >= LCD_WIDTH) || ((unsigned) y >= LCD_HEIGHT))
465 return; 465 return;
466 if (((unsigned)(x + nx)) >= LCD_WIDTH)
467 nx = LCD_WIDTH - x;
468 if (((unsigned)(y + ny)) >= LCD_HEIGHT)
469 ny = LCD_HEIGHT - y;
470 466
471 shift = y & 7; 467 stride = nx; /* otherwise right-clipping will destroy the image */
472 dst2 = &lcd_framebuffer[y/8][x];
473 468
474 /* short cut for byte aligned match (e.g. standard text) */ 469 if (((unsigned) (x + nx)) >= LCD_WIDTH)
475 if (!shift && clear && ny==8) 470 nx = LCD_WIDTH - x;
471 if (((unsigned) (y + ny)) >= LCD_HEIGHT)
472 ny = LCD_HEIGHT - y;
473
474 dst = &lcd_framebuffer[y >> 3][x];
475 shift = y & 7;
476
477 if (!shift && clear) /* shortcut for byte aligned match with clear */
476 { 478 {
477 memcpy(dst2, src, nx); 479 while (ny >= 8) /* all full rows */
478 return; 480 {
481 memcpy(dst, src, nx);
482 src += stride;
483 dst += LCD_WIDTH;
484 ny -= 8;
485 }
486 if (ny == 0) /* nothing left to do? */
487 return;
488 /* last partial row to do by default routine */
479 } 489 }
480 490
481 ny += shift; 491 ny += shift;
482 492
483 /* Calculate bit masks */ 493 /* Calculate bit masks */
484 mask4 = ~(0xfe << ((ny-1) & 7)); 494 mask4 = ~(0xfe << ((ny-1) & 7)); /* data mask for last partial row */
485 if (clear) 495 if (clear)
486 { 496 {
487 mask = ~(0xff << shift); 497 mask1 = ~(0xff << shift); /* clearing of first partial row */
488 mask2 = 0; 498 mask2 = 0; /* clearing of intermediate (full) rows */
489 mask3 = ~mask4; 499 mask3 = ~mask4; /* clearing of last partial row */
490 if (ny <= 8) 500 if (ny <= 8)
491 mask3 |= mask; 501 mask3 |= mask1;
492 } 502 }
493 else 503 else
494 mask = mask2 = mask3 = 0xff; 504 mask1 = mask2 = mask3 = 0xff;
495 505
496 /* Loop for each column */ 506 /* Loop for each column */
497 for (x = 0; x < nx; x++) 507 for (x = 0; x < nx; x++)
498 { 508 {
499 dst = dst2; 509 src_col = src++;
500 dst2++; 510 dst_col = dst++;
501 data = 0; 511 data = 0;
502 y = 0; 512 y = 0;
503 513
504 if (ny > 8) 514 if (ny > 8)
505 { 515 {
506 /* First partial row */ 516 /* First partial row */
507 data = *src++ << shift; 517 data = *src_col << shift;
508 *dst = (*dst & mask) | data; 518 *dst_col = (*dst_col & mask1) | data;
519 src_col += stride;
520 dst_col += LCD_WIDTH;
509 data >>= 8; 521 data >>= 8;
510 dst += LCD_WIDTH;
511 522
512 /* Intermediate rows */ 523 /* Intermediate rows */
513 for (y = 8; y < ny-8; y += 8) 524 for (y = 8; y < ny-8; y += 8)
514 { 525 {
515 data |= *src++ << shift; 526 data |= *src_col << shift;
516 *dst = (*dst & mask2) | data; 527 *dst_col = (*dst_col & mask2) | data;
528 src_col += stride;
529 dst_col += LCD_WIDTH;
517 data >>= 8; 530 data >>= 8;
518 dst += LCD_WIDTH;
519 } 531 }
520 } 532 }
521 533
522 /* Last partial row */ 534 /* Last partial row */
523 if (y + shift < ny) 535 if (y + shift < ny)
524 data |= *src++ << shift; 536 data |= *src_col << shift;
525 *dst = (*dst & mask3) | (data & mask4); 537 *dst_col = (*dst_col & mask3) | (data & mask4);
526 } 538 }
527} 539}
528 540
529/* 541/*
530 * Draw a rectangle with upper left corner at (x, y) 542 * Draw a rectangle with upper left corner at (x, y)
531 * and size (nx, ny) 543 * and size (nx, ny)
532 */ 544 */
diff --git a/firmware/font.c b/firmware/font.c
index f1762ba698..7c83923904 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -300,6 +300,7 @@ static void rotate_font_bits(struct font* pf)
300 * Take an bitmap_t bitmap and convert to Rockbox format. 300 * Take an bitmap_t bitmap and convert to Rockbox format.
301 * Used for converting font glyphs for the time being. 301 * Used for converting font glyphs for the time being.
302 * Can use for standard X11 and Win32 images as well. 302 * Can use for standard X11 and Win32 images as well.
303 * See format description in lcd-recorder.c
303 * 304 *
304 * Doing it this way keeps fonts in standard formats, 305 * Doing it this way keeps fonts in standard formats,
305 * as well as keeping Rockbox hw bitmap format. 306 * as well as keeping Rockbox hw bitmap format.
@@ -308,52 +309,44 @@ static void rotleft(unsigned char *dst, bitmap_t *src, unsigned int width,
308 unsigned int height) 309 unsigned int height)
309{ 310{
310 unsigned int i,j; 311 unsigned int i,j;
311 unsigned int dst_col = 0; /* destination column*/
312 unsigned int dst_shift = 0; /* destination shift amount*/
313 unsigned int dst_linelen; /* # bytes per output row*/
314 unsigned int src_words; /* # words of input image*/ 312 unsigned int src_words; /* # words of input image*/
315 313 unsigned int dst_mask; /* bit mask for destination */
316 /* calc bytes per output row*/ 314 bitmap_t src_mask; /* bit mask for source */
317 dst_linelen = (height-1)/8+1;
318 315
319 /* calc words of input image*/ 316 /* calc words of input image*/
320 src_words = BITMAP_WORDS(width) * height; 317 src_words = BITMAP_WORDS(width) * height;
321 318
322 /* clear background*/ 319 /* clear background*/
323 memset(dst, 0, dst_linelen*width); 320 memset(dst, 0, ((height + 7) / 8) * width);
324 321
325 for (i=0; i < src_words; i++) { 322 dst_mask = 1;
326 bitmap_t srcmap; /* current src input bit*/
327 bitmap_t dstmap; /* current dst output bit*/
328
329 /* calc src input bit*/
330 srcmap = 1 << (sizeof(bitmap_t)*8-1);
331 323
332 /* calc dst output bit*/ 324 for (i=0; i < src_words; i++) {
333 if (i>0 && (i%8==0)) {
334 ++dst_col;
335 dst_shift = 0;
336 }
337 dstmap = 1 << dst_shift++;
338 325
326 /* calc src input bit*/
327 src_mask = 1 << (sizeof (bitmap_t) * 8 - 1);
328
339 /* for each input column...*/ 329 /* for each input column...*/
340 for(j=0; j < width; j++) { 330 for(j=0; j < width; j++) {
341 331
342 /* calc input bitmask*/ 332 /* if set in input, set in rotated output */
343 bitmap_t bit = srcmap >> j; 333 if (src[i] & src_mask)
344 if (bit==0) { 334 dst[j] |= dst_mask;
345 srcmap = 1 << (sizeof(bitmap_t)*8-1);
346 bit = srcmap >> (j % 16);
347 }
348 335
349 /* if set in input, set in rotated output*/ 336 src_mask >>= 1; /* next input bit */
350 if (bit & src[i]) { 337 if (src_mask == 0) /* input word done? */
351 /* input column j becomes output row*/ 338 {
352 dst[j*dst_linelen + dst_col] |= dstmap; 339 src_mask = 1 << (sizeof (bitmap_t) * 8 - 1);
340 i++; /* next input word */
353 } 341 }
354 /*debugf((bit & src[i])? "*": ".");*/
355 } 342 }
356 /*debugf("\n");*/ 343
344 dst_mask <<= 1; /* next output bit (row) */
345 if (dst_mask > (1 << 7)) /* output bit > 7? */
346 {
347 dst_mask = 1;
348 dst += width; /* next output byte row */
349 }
357 } 350 }
358} 351}
359#endif /* HAVE_LCD_BITMAP */ 352#endif /* HAVE_LCD_BITMAP */