diff options
Diffstat (limited to 'apps/plugins/lib/gray.c')
-rw-r--r-- | apps/plugins/lib/gray.c | 212 |
1 files changed, 145 insertions, 67 deletions
diff --git a/apps/plugins/lib/gray.c b/apps/plugins/lib/gray.c index f026ff7cd4..a18f3f7644 100644 --- a/apps/plugins/lib/gray.c +++ b/apps/plugins/lib/gray.c | |||
@@ -38,7 +38,8 @@ | |||
38 | #define GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ | 38 | #define GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ |
39 | 39 | ||
40 | /* unsigned 16 bit multiplication (a single instruction on the SH) */ | 40 | /* unsigned 16 bit multiplication (a single instruction on the SH) */ |
41 | #define MULU16(a, b) (((unsigned short) (a)) * ((unsigned short) (b))) | 41 | #define MULU16(a, b) ((unsigned long) \ |
42 | (((unsigned short) (a)) * ((unsigned short) (b)))) | ||
42 | 43 | ||
43 | typedef struct | 44 | typedef struct |
44 | { | 45 | { |
@@ -52,8 +53,9 @@ typedef struct | |||
52 | int cur_plane; /* for the timer isr */ | 53 | int cur_plane; /* for the timer isr */ |
53 | unsigned long randmask; /* mask for random value in graypixel() */ | 54 | unsigned long randmask; /* mask for random value in graypixel() */ |
54 | unsigned long flags; /* various flags, see #defines */ | 55 | unsigned long flags; /* various flags, see #defines */ |
55 | unsigned char *data; /* pointer to start of bitplane data */ | ||
56 | unsigned long *bitpattern; /* pointer to start of pattern table */ | 56 | unsigned long *bitpattern; /* pointer to start of pattern table */ |
57 | unsigned char *data; /* pointer to start of bitplane data */ | ||
58 | int curfont; /* current selected font */ | ||
57 | } tGraybuf; | 59 | } tGraybuf; |
58 | 60 | ||
59 | static struct plugin_api *rb = NULL; /* global api struct pointer */ | 61 | static struct plugin_api *rb = NULL; /* global api struct pointer */ |
@@ -103,26 +105,24 @@ static void graypixel(int x, int y, unsigned long pattern) | |||
103 | * pattern randomly, otherwise you would get flicker and/or moire. | 105 | * pattern randomly, otherwise you would get flicker and/or moire. |
104 | * Since rand() is relatively slow, I've implemented a simple, but very | 106 | * Since rand() is relatively slow, I've implemented a simple, but very |
105 | * fast pseudo-random generator based on linear congruency in assembler. | 107 | * fast pseudo-random generator based on linear congruency in assembler. |
106 | * It delivers 16 pseudo-random bits in each iteration. */ | 108 | * It delivers max. 16 pseudo-random bits in each iteration. */ |
107 | 109 | ||
108 | /* simple but fast pseudo-random generator */ | 110 | /* simple but fast pseudo-random generator */ |
109 | asm( | 111 | asm( |
110 | "mov.w @%1,%0 \n" /* load last value */ | ||
111 | "mov #75,r1 \n" | 112 | "mov #75,r1 \n" |
112 | "mulu %0,r1 \n" /* multiply by 75 */ | 113 | "mulu %1,r1 \n" /* multiply by 75 */ |
113 | "sts macl,%0 \n" /* get result */ | 114 | "sts macl,%1 \n" /* get result */ |
114 | "add #74,%0 \n" /* add another 74 */ | 115 | "add #74,%1 \n" /* add another 74 */ |
115 | "mov.w %0,@%1 \n" /* store new value */ | ||
116 | /* Since the lower bits are not very random: */ | 116 | /* Since the lower bits are not very random: */ |
117 | "shlr8 %0 \n" /* get bits 8..15 (need max. 5) */ | 117 | "swap.b %1,%0 \n" /* get bits 8..15 (need max. 5) */ |
118 | "and %2,%0 \n" /* mask out unneeded bits */ | 118 | "and %2,%0 \n" /* mask out unneeded bits */ |
119 | : /* outputs */ | 119 | : /* outputs */ |
120 | /* %0 */ "=&r"(random) | 120 | /* %0 */ "=&r"(random), |
121 | /* %1, in & out */ "+r"(gray_random_buffer) | ||
121 | : /* inputs */ | 122 | : /* inputs */ |
122 | /* %1 */ "r"(&gray_random_buffer), | ||
123 | /* %2 */ "r"(graybuf->randmask) | 123 | /* %2 */ "r"(graybuf->randmask) |
124 | : /* clobbers */ | 124 | : /* clobbers */ |
125 | "r1","macl" | 125 | "r1", "macl" |
126 | ); | 126 | ); |
127 | 127 | ||
128 | /* precalculate mask and byte address in first bitplane */ | 128 | /* precalculate mask and byte address in first bitplane */ |
@@ -233,12 +233,16 @@ static void graypixel(int x, int y, unsigned long pattern) | |||
233 | * for larger rectangles and graymaps */ | 233 | * for larger rectangles and graymaps */ |
234 | static void grayblock(int x, int by, unsigned char* src, int stride) | 234 | static void grayblock(int x, int by, unsigned char* src, int stride) |
235 | { | 235 | { |
236 | register unsigned char *address, *end_addr; | ||
237 | unsigned long pat_stack[8]; | ||
238 | register unsigned long *pat_ptr = &pat_stack[8]; /* behind last element */ | ||
239 | |||
236 | /* precalculate the bit patterns with random shifts (same RNG as graypixel, | 240 | /* precalculate the bit patterns with random shifts (same RNG as graypixel, |
237 | * see there for an explanation) for all 8 pixels and put them on the | 241 | * see there for an explanation) for all 8 pixels and put them on an |
238 | * stack (!) */ | 242 | * extra stack */ |
239 | asm( | 243 | asm( |
240 | "mova .gb_reload,r0 \n" /* set default loopback address */ | 244 | "mova .gb_reload,r0 \n" /* set default loopback address */ |
241 | "tst %1,%1 \n" /* stride == 0 ? */ | 245 | "tst %3,%3 \n" /* stride == 0 ? */ |
242 | "bf .gb_needreload \n" /* no: keep that address */ | 246 | "bf .gb_needreload \n" /* no: keep that address */ |
243 | "mova .gb_reuse,r0 \n" /* yes: set shortcut (no reload) */ | 247 | "mova .gb_reuse,r0 \n" /* yes: set shortcut (no reload) */ |
244 | ".gb_needreload: \n" | 248 | ".gb_needreload: \n" |
@@ -247,46 +251,45 @@ static void grayblock(int x, int by, unsigned char* src, int stride) | |||
247 | 251 | ||
248 | ".align 2 \n" /** load pattern for pixel **/ | 252 | ".align 2 \n" /** load pattern for pixel **/ |
249 | ".gb_reload: \n" | 253 | ".gb_reload: \n" |
250 | "mov.b @%0,r0 \n" /* load src byte */ | 254 | "mov.b @%2,r0 \n" /* load src byte */ |
255 | "nop \n" /* align here, saves a pipeline stall */ | ||
251 | "extu.b r0,r0 \n" /* extend unsigned */ | 256 | "extu.b r0,r0 \n" /* extend unsigned */ |
252 | "mulu %2,r0 \n" /* macl = byte * depth; */ | 257 | "mulu %4,r0 \n" /* macl = byte * depth; */ |
253 | "add %1,%0 \n" /* src += stride; */ | 258 | "add %3,%2 \n" /* src += stride; */ |
254 | "sts macl,r4 \n" /* r4 = macl; */ | 259 | "sts macl,r4 \n" /* r4 = macl; */ |
255 | "add r4,r0 \n" /* byte += r4; */ | 260 | "add r4,r0 \n" /* byte += r4; */ |
256 | "shlr8 r0 \n" /* byte >>= 8; */ | 261 | "shlr8 r0 \n" /* byte >>= 8; */ |
257 | "shll2 r0 \n" | 262 | "shll2 r0 \n" |
258 | "mov.l @(r0,%3),r4 \n" /* r4 = bitpattern[byte]; */ | 263 | "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */ |
259 | 264 | ||
260 | ".align 2 \n" /** RNG **/ | 265 | ".align 2 \n" /** RNG **/ |
261 | ".gb_reuse: \n" | 266 | ".gb_reuse: \n" |
262 | "mov.w @%4,r1 \n" /* load last value */ | ||
263 | "mov #75,r0 \n" | 267 | "mov #75,r0 \n" |
264 | "mulu r0,r1 \n" /* multiply by 75 */ | 268 | "mulu r0,%1 \n" /* multiply by 75 */ |
265 | "sts macl,r1 \n" | 269 | "sts macl,%1 \n" |
266 | "add #74,r1 \n" /* add another 74 */ | 270 | "add #74,%1 \n" /* add another 74 */ |
267 | "mov.w r1,@%4 \n" /* store new value */ | ||
268 | /* Since the lower bits are not very random: */ | 271 | /* Since the lower bits are not very random: */ |
269 | "shlr8 r1 \n" /* get bits 8..15 (need max. 5) */ | 272 | "swap.b %1,r1 \n" /* get bits 8..15 (need max. 5) */ |
270 | "and %5,r1 \n" /* mask out unneeded bits */ | 273 | "and %6,r1 \n" /* mask out unneeded bits */ |
271 | 274 | ||
272 | "cmp/hs %2,r1 \n" /* random >= depth ? */ | 275 | "cmp/hs %4,r1 \n" /* random >= depth ? */ |
273 | "bf .gb_ntrim \n" | 276 | "bf .gb_ntrim \n" |
274 | "sub %2,r1 \n" /* yes: random -= depth; */ | 277 | "sub %4,r1 \n" /* yes: random -= depth; */ |
275 | ".gb_ntrim: \n" | 278 | ".gb_ntrim: \n" |
276 | 279 | ||
277 | "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ | 280 | "mov.l .ashlsi3,r0 \n" /** rotate pattern **/ |
278 | "jsr @r0 \n" /* shift r4 left by r1 */ | 281 | "jsr @r0 \n" /* r4 -> r0, shift left by r5 */ |
279 | "mov r1,r5 \n" | 282 | "mov r1,r5 \n" |
280 | 283 | ||
281 | "mov %2,r5 \n" | 284 | "mov %4,r5 \n" |
282 | "sub r1,r5 \n" /* r5 = depth - r1 */ | 285 | "sub r1,r5 \n" /* r5 = depth - r1 */ |
283 | "mov.l .lshrsi3,r1 \n" | 286 | "mov.l .lshrsi3,r1 \n" |
284 | "jsr @r1 \n" /* shift r4 right by r5 */ | 287 | "jsr @r1 \n" /* r4 -> r0, shift right by r5 */ |
285 | "mov r0,r1 \n" /* last result stored in r1 */ | 288 | "mov r0,r1 \n" /* store previous result in r1 */ |
286 | 289 | ||
287 | "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ | 290 | "or r1,r0 \n" /* rotated_pattern = r0 | r1 */ |
288 | "mov.l r0,@-r15 \n" /* push pattern */ | 291 | "mov.l r0,@-%0 \n" /* push on pattern stack */ |
289 | 292 | ||
290 | "cmp/pl r3 \n" /* loop count > 0? */ | 293 | "cmp/pl r3 \n" /* loop count > 0? */ |
291 | "bf .gb_patdone \n" /* no: done */ | 294 | "bf .gb_patdone \n" /* no: done */ |
292 | 295 | ||
@@ -302,34 +305,33 @@ static void grayblock(int x, int by, unsigned char* src, int stride) | |||
302 | 305 | ||
303 | ".gb_patdone: \n" | 306 | ".gb_patdone: \n" |
304 | : /* outputs */ | 307 | : /* outputs */ |
308 | /* %0, in & out */ "+r"(pat_ptr), | ||
309 | /* %1, in & out */ "+r"(gray_random_buffer) | ||
305 | : /* inputs */ | 310 | : /* inputs */ |
306 | /* %0 */ "r"(src), | 311 | /* %2 */ "r"(src), |
307 | /* %1 */ "r"(stride), | 312 | /* %3 */ "r"(stride), |
308 | /* %2 */ "r"(graybuf->depth), | 313 | /* %4 */ "r"(graybuf->depth), |
309 | /* %3 */ "r"(graybuf->bitpattern), | 314 | /* %5 */ "r"(graybuf->bitpattern), |
310 | /* %4 */ "r"(&gray_random_buffer), | 315 | /* %6 */ "r"(graybuf->randmask) |
311 | /* %5 */ "r"(graybuf->randmask) | ||
312 | : /* clobbers */ | 316 | : /* clobbers */ |
313 | "r0", "r1", "r2", "r3", "r4", "r5", "macl" | 317 | "r0", "r1", "r2", "r3", "r4", "r5", "macl" |
314 | ); | 318 | ); |
315 | 319 | ||
316 | /* calculate start address in first bitplane and end address */ | 320 | /* calculate start address in first bitplane and end address */ |
317 | register unsigned char *address = graybuf->data + x | 321 | address = graybuf->data + x + MULU16(graybuf->width, by); |
318 | + MULU16(graybuf->width, by); | 322 | end_addr = address + MULU16(graybuf->depth, graybuf->plane_size); |
319 | register unsigned char *end_addr = address | ||
320 | + MULU16(graybuf->depth, graybuf->plane_size); | ||
321 | 323 | ||
322 | /* set the bits for all 8 pixels in all bytes according to the | 324 | /* set the bits for all 8 pixels in all bytes according to the |
323 | * precalculated patterns on the stack */ | 325 | * precalculated patterns on the pattern stack */ |
324 | asm ( | 326 | asm ( |
325 | "mov.l @r15+,r1 \n" /* pop all 8 patterns */ | 327 | "mov.l @%3+,r1 \n" /* pop all 8 patterns */ |
326 | "mov.l @r15+,r2 \n" | 328 | "mov.l @%3+,r2 \n" |
327 | "mov.l @r15+,r3 \n" | 329 | "mov.l @%3+,r3 \n" |
328 | "mov.l @r15+,r4 \n" | 330 | "mov.l @%3+,r4 \n" |
329 | "mov.l @r15+,r5 \n" | 331 | "mov.l @%3+,r5 \n" |
330 | "mov.l @r15+,r6 \n" | 332 | "mov.l @%3+,r6 \n" |
331 | "mov.l @r15+,r7 \n" | 333 | "mov.l @%3+,r7 \n" |
332 | "mov.l @r15+,r8 \n" | 334 | "mov.l @%3+,%3 \n" |
333 | 335 | ||
334 | ".gb_loop: \n" /* loop for all bitplanes */ | 336 | ".gb_loop: \n" /* loop for all bitplanes */ |
335 | "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ | 337 | "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */ |
@@ -346,7 +348,7 @@ static void grayblock(int x, int by, unsigned char* src, int stride) | |||
346 | "rotcl r0 \n" | 348 | "rotcl r0 \n" |
347 | "shlr r7 \n" | 349 | "shlr r7 \n" |
348 | "rotcl r0 \n" | 350 | "rotcl r0 \n" |
349 | "shlr r8 \n" | 351 | "shlr %3 \n" |
350 | "rotcl r0 \n" | 352 | "rotcl r0 \n" |
351 | "mov.b r0,@%0 \n" /* store byte to bitplane */ | 353 | "mov.b r0,@%0 \n" /* store byte to bitplane */ |
352 | "add %2,%0 \n" /* advance to next bitplane */ | 354 | "add %2,%0 \n" /* advance to next bitplane */ |
@@ -356,9 +358,10 @@ static void grayblock(int x, int by, unsigned char* src, int stride) | |||
356 | : /* inputs */ | 358 | : /* inputs */ |
357 | /* %0 */ "r"(address), | 359 | /* %0 */ "r"(address), |
358 | /* %1 */ "r"(end_addr), | 360 | /* %1 */ "r"(end_addr), |
359 | /* %2 */ "r"(graybuf->plane_size) | 361 | /* %2 */ "r"(graybuf->plane_size), |
362 | /* %3 */ "r"(pat_ptr) | ||
360 | : /* clobbers */ | 363 | : /* clobbers */ |
361 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8" | 364 | "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" |
362 | ); | 365 | ); |
363 | } | 366 | } |
364 | 367 | ||
@@ -445,7 +448,7 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, | |||
445 | gbuf += align; | 448 | gbuf += align; |
446 | gbuf_size -= align; | 449 | gbuf_size -= align; |
447 | 450 | ||
448 | plane_size = width * bheight; | 451 | plane_size = MULU16(width, bheight); |
449 | possible_depth = (gbuf_size - sizeof(tGraybuf) - sizeof(long)) | 452 | possible_depth = (gbuf_size - sizeof(tGraybuf) - sizeof(long)) |
450 | / (plane_size + sizeof(long)); | 453 | / (plane_size + sizeof(long)); |
451 | 454 | ||
@@ -466,9 +469,9 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, | |||
466 | graybuf->depth = depth; | 469 | graybuf->depth = depth; |
467 | graybuf->cur_plane = 0; | 470 | graybuf->cur_plane = 0; |
468 | graybuf->flags = 0; | 471 | graybuf->flags = 0; |
469 | graybuf->data = gbuf + sizeof(tGraybuf); | 472 | graybuf->bitpattern = (unsigned long *) gbuf + sizeof(tGraybuf); |
470 | graybuf->bitpattern = (unsigned long *) (graybuf->data | 473 | graybuf->data = (unsigned char *) (graybuf->bitpattern + depth + 1); |
471 | + depth * plane_size); | 474 | graybuf->curfont = FONT_SYSFIXED; |
472 | 475 | ||
473 | i = depth; | 476 | i = depth; |
474 | j = 8; | 477 | j = 8; |
@@ -477,10 +480,10 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, | |||
477 | i >>= 1; | 480 | i >>= 1; |
478 | j--; | 481 | j--; |
479 | } | 482 | } |
480 | graybuf->randmask = 0xFF >> j; | 483 | graybuf->randmask = 0xFFu >> j; |
481 | 484 | ||
482 | /* initial state is all white */ | 485 | /* initial state is all white */ |
483 | rb->memset(graybuf->data, 0, depth * plane_size); | 486 | rb->memset(graybuf->data, 0, MULU16(depth, plane_size)); |
484 | 487 | ||
485 | /* Precalculate the bit patterns for all possible pixel values */ | 488 | /* Precalculate the bit patterns for all possible pixel values */ |
486 | for (i = 0; i <= depth; i++) | 489 | for (i = 0; i <= depth; i++) |
@@ -506,7 +509,7 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, | |||
506 | if (buf_taken) /* caller requested info about space taken */ | 509 | if (buf_taken) /* caller requested info about space taken */ |
507 | { | 510 | { |
508 | *buf_taken = sizeof(tGraybuf) + sizeof(long) | 511 | *buf_taken = sizeof(tGraybuf) + sizeof(long) |
509 | + (plane_size + sizeof(long)) * depth + align; | 512 | + MULU16(plane_size + sizeof(long), depth) + align; |
510 | } | 513 | } |
511 | 514 | ||
512 | return depth; | 515 | return depth; |
@@ -1391,15 +1394,15 @@ void gray_invertrect(int x1, int y1, int x2, int y2) | |||
1391 | 1394 | ||
1392 | if (yb1 == yb2) | 1395 | if (yb1 == yb2) |
1393 | { | 1396 | { |
1394 | mask = 0xFF << (y1 & 7); | 1397 | mask = 0xFFu << (y1 & 7); |
1395 | mask &= 0xFF >> (7 - (y2 & 7)); | 1398 | mask &= 0xFFu >> (7 - (y2 & 7)); |
1396 | 1399 | ||
1397 | for (x = x1; x <= x2; x++) | 1400 | for (x = x1; x <= x2; x++) |
1398 | grayinvertmasked(x, yb1, mask); | 1401 | grayinvertmasked(x, yb1, mask); |
1399 | } | 1402 | } |
1400 | else | 1403 | else |
1401 | { | 1404 | { |
1402 | mask = 0xFF << (y1 & 7); | 1405 | mask = 0xFFu << (y1 & 7); |
1403 | 1406 | ||
1404 | for (x = x1; x <= x2; x++) | 1407 | for (x = x1; x <= x2; x++) |
1405 | grayinvertmasked(x, yb1, mask); | 1408 | grayinvertmasked(x, yb1, mask); |
@@ -1410,7 +1413,7 @@ void gray_invertrect(int x1, int y1, int x2, int y2) | |||
1410 | grayinvertmasked(x, yb, 0xFF); | 1413 | grayinvertmasked(x, yb, 0xFF); |
1411 | } | 1414 | } |
1412 | 1415 | ||
1413 | mask = 0xFF >> (7 - (y2 & 7)); | 1416 | mask = 0xFFu >> (7 - (y2 & 7)); |
1414 | 1417 | ||
1415 | for (x = x1; x <= x2; x++) | 1418 | for (x = x1; x <= x2; x++) |
1416 | grayinvertmasked(x, yb2, mask); | 1419 | grayinvertmasked(x, yb2, mask); |
@@ -1539,6 +1542,81 @@ void gray_drawbitmap(unsigned char *src, int x, int y, int nx, int ny, | |||
1539 | } | 1542 | } |
1540 | } | 1543 | } |
1541 | 1544 | ||
1545 | /* Set font for the font routines | ||
1546 | * | ||
1547 | * newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox | ||
1548 | * core routines | ||
1549 | */ | ||
1550 | void gray_setfont(int newfont) | ||
1551 | { | ||
1552 | graybuf->curfont = newfont; | ||
1553 | } | ||
1554 | |||
1555 | /* Calculate width and height of the given text in pixels when rendered with | ||
1556 | * the currently selected font. | ||
1557 | * | ||
1558 | * This works exactly the same way as the core lcd_getstringsize(), only that | ||
1559 | * it uses the selected font for grayscale. | ||
1560 | */ | ||
1561 | int gray_getstringsize(unsigned char *str, int *w, int *h) | ||
1562 | { | ||
1563 | int ch; | ||
1564 | int width = 0; | ||
1565 | struct font* pf = rb->font_get(graybuf->curfont); | ||
1566 | |||
1567 | while ((ch = *str++)) | ||
1568 | { | ||
1569 | /* check input range */ | ||
1570 | if (ch < pf->firstchar || ch >= pf->firstchar + pf->size) | ||
1571 | ch = pf->defaultchar; | ||
1572 | ch -= pf->firstchar; | ||
1573 | |||
1574 | /* get proportional width */ | ||
1575 | width += pf->width ? pf->width[ch] : pf->maxwidth; | ||
1576 | } | ||
1577 | if (w) | ||
1578 | *w = width; | ||
1579 | if (h) | ||
1580 | *h = pf->height; | ||
1581 | return width; | ||
1582 | } | ||
1583 | |||
1584 | /* Display text with specified foreground and background shades | ||
1585 | * | ||
1586 | * If draw_bg is false, only foreground pixels are drawn, so the background | ||
1587 | * is transparent. In this case bg_brightness is ignored. | ||
1588 | */ | ||
1589 | void gray_putsxy(int x, int y, unsigned char *str, bool draw_bg, | ||
1590 | int fg_brightness, int bg_brightness) | ||
1591 | { | ||
1592 | int ch, width; | ||
1593 | bitmap_t *bits; | ||
1594 | struct font *pf = rb->font_get(graybuf->curfont); | ||
1595 | |||
1596 | if (graybuf == NULL | ||
1597 | || (unsigned) x >= (unsigned) graybuf->width | ||
1598 | || (unsigned) y >= (unsigned) graybuf->height | ||
1599 | || (unsigned) fg_brightness > 255 | ||
1600 | || (unsigned) bg_brightness > 255) | ||
1601 | return; | ||
1602 | |||
1603 | while ((ch = *str++) != '\0' && x < graybuf->width) | ||
1604 | { | ||
1605 | /* check input range */ | ||
1606 | if (ch < pf->firstchar || ch >= pf->firstchar + pf->size) | ||
1607 | ch = pf->defaultchar; | ||
1608 | ch -= pf->firstchar; | ||
1609 | |||
1610 | /* get proportional width and glyph bits */ | ||
1611 | width = pf->width ? pf->width[ch] : pf->maxwidth; | ||
1612 | bits = pf->bits + (pf->offset ? pf->offset[ch] : (pf->height * ch)); | ||
1613 | |||
1614 | gray_drawbitmap((unsigned char*) bits, x, y, width, pf->height, | ||
1615 | width, draw_bg, fg_brightness, bg_brightness); | ||
1616 | x += width; | ||
1617 | } | ||
1618 | } | ||
1619 | |||
1542 | #endif // #ifdef HAVE_LCD_BITMAP | 1620 | #endif // #ifdef HAVE_LCD_BITMAP |
1543 | #endif // #ifndef SIMULATOR | 1621 | #endif // #ifndef SIMULATOR |
1544 | 1622 | ||