diff options
Diffstat (limited to 'apps/plugins/lib/grey_draw.c')
-rw-r--r-- | apps/plugins/lib/grey_draw.c | 681 |
1 files changed, 681 insertions, 0 deletions
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c new file mode 100644 index 0000000000..e243b5fbce --- /dev/null +++ b/apps/plugins/lib/grey_draw.c | |||
@@ -0,0 +1,681 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * New greyscale framework | ||
11 | * Drawing functions | ||
12 | * | ||
13 | * This is a generic framework to display 129 shades of grey on low-depth | ||
14 | * bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins. | ||
15 | * | ||
16 | * Copyright (C) 2008 Jens Arnold | ||
17 | * | ||
18 | * All files in this archive are subject to the GNU General Public License. | ||
19 | * See the file COPYING in the source tree root for full license agreement. | ||
20 | * | ||
21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
22 | * KIND, either express or implied. | ||
23 | * | ||
24 | ****************************************************************************/ | ||
25 | |||
26 | #include "plugin.h" | ||
27 | #include "grey.h" | ||
28 | |||
29 | /*** low-level drawing functions ***/ | ||
30 | |||
31 | static void setpixel(unsigned char *address) | ||
32 | { | ||
33 | *address = _grey_info.fg_val; | ||
34 | } | ||
35 | |||
36 | static void clearpixel(unsigned char *address) | ||
37 | { | ||
38 | *address = _grey_info.bg_val; | ||
39 | } | ||
40 | |||
41 | static void flippixel(unsigned char *address) | ||
42 | { | ||
43 | *address = 128 - *address; | ||
44 | } | ||
45 | |||
46 | static void nopixel(unsigned char *address) | ||
47 | { | ||
48 | (void)address; | ||
49 | } | ||
50 | |||
51 | void (* const _grey_pixelfuncs[8])(unsigned char *address) = { | ||
52 | flippixel, nopixel, setpixel, setpixel, | ||
53 | nopixel, clearpixel, nopixel, clearpixel | ||
54 | }; | ||
55 | |||
56 | /*** Drawing functions ***/ | ||
57 | |||
58 | /* Clear the whole display */ | ||
59 | void grey_clear_display(void) | ||
60 | { | ||
61 | int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ? | ||
62 | _grey_info.fg_val : _grey_info.bg_val; | ||
63 | |||
64 | _grey_rb->memset(_grey_info.buffer, value, | ||
65 | _GREY_MULUQ(_grey_info.width, _grey_info.height)); | ||
66 | } | ||
67 | |||
68 | /* Set a single pixel */ | ||
69 | void grey_drawpixel(int x, int y) | ||
70 | { | ||
71 | if (((unsigned)x < (unsigned)_grey_info.width) | ||
72 | && ((unsigned)y < (unsigned)_grey_info.height)) | ||
73 | _grey_pixelfuncs[_grey_info.drawmode](&_grey_info.buffer[_GREY_MULUQ( | ||
74 | _grey_info.width, y) + x]); | ||
75 | } | ||
76 | |||
77 | /* Draw a line */ | ||
78 | void grey_drawline(int x1, int y1, int x2, int y2) | ||
79 | { | ||
80 | int numpixels; | ||
81 | int i; | ||
82 | int deltax, deltay; | ||
83 | int d, dinc1, dinc2; | ||
84 | int x, xinc1, xinc2; | ||
85 | int y, yinc1, yinc2; | ||
86 | void (*pfunc)(unsigned char *address) = _grey_pixelfuncs[_grey_info.drawmode]; | ||
87 | |||
88 | deltax = abs(x2 - x1); | ||
89 | deltay = abs(y2 - y1); | ||
90 | xinc2 = 1; | ||
91 | yinc2 = 1; | ||
92 | |||
93 | if (deltax >= deltay) | ||
94 | { | ||
95 | numpixels = deltax; | ||
96 | d = 2 * deltay - deltax; | ||
97 | dinc1 = deltay * 2; | ||
98 | dinc2 = (deltay - deltax) * 2; | ||
99 | xinc1 = 1; | ||
100 | yinc1 = 0; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | numpixels = deltay; | ||
105 | d = 2 * deltax - deltay; | ||
106 | dinc1 = deltax * 2; | ||
107 | dinc2 = (deltax - deltay) * 2; | ||
108 | xinc1 = 0; | ||
109 | yinc1 = 1; | ||
110 | } | ||
111 | numpixels++; /* include endpoints */ | ||
112 | |||
113 | if (x1 > x2) | ||
114 | { | ||
115 | xinc1 = -xinc1; | ||
116 | xinc2 = -xinc2; | ||
117 | } | ||
118 | |||
119 | if (y1 > y2) | ||
120 | { | ||
121 | yinc1 = -yinc1; | ||
122 | yinc2 = -yinc2; | ||
123 | } | ||
124 | |||
125 | x = x1; | ||
126 | y = y1; | ||
127 | |||
128 | for (i = 0; i < numpixels; i++) | ||
129 | { | ||
130 | if (((unsigned)x < (unsigned)_grey_info.width) | ||
131 | && ((unsigned)y < (unsigned)_grey_info.height)) | ||
132 | pfunc(&_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]); | ||
133 | |||
134 | if (d < 0) | ||
135 | { | ||
136 | d += dinc1; | ||
137 | x += xinc1; | ||
138 | y += yinc1; | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | d += dinc2; | ||
143 | x += xinc2; | ||
144 | y += yinc2; | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | /* Draw a horizontal line (optimised) */ | ||
150 | void grey_hline(int x1, int x2, int y) | ||
151 | { | ||
152 | int x; | ||
153 | int value = 0; | ||
154 | unsigned char *dst; | ||
155 | bool fillopt = false; | ||
156 | void (*pfunc)(unsigned char *address); | ||
157 | |||
158 | /* direction flip */ | ||
159 | if (x2 < x1) | ||
160 | { | ||
161 | x = x1; | ||
162 | x1 = x2; | ||
163 | x2 = x; | ||
164 | } | ||
165 | |||
166 | /* nothing to draw? */ | ||
167 | if (((unsigned)y >= (unsigned)_grey_info.height) | ||
168 | || (x1 >= _grey_info.width) || (x2 < 0)) | ||
169 | return; | ||
170 | |||
171 | /* clipping */ | ||
172 | if (x1 < 0) | ||
173 | x1 = 0; | ||
174 | if (x2 >= _grey_info.width) | ||
175 | x2 = _grey_info.width - 1; | ||
176 | |||
177 | if (_grey_info.drawmode & DRMODE_INVERSEVID) | ||
178 | { | ||
179 | if (_grey_info.drawmode & DRMODE_BG) | ||
180 | { | ||
181 | fillopt = true; | ||
182 | value = _grey_info.bg_val; | ||
183 | } | ||
184 | } | ||
185 | else | ||
186 | { | ||
187 | if (_grey_info.drawmode & DRMODE_FG) | ||
188 | { | ||
189 | fillopt = true; | ||
190 | value = _grey_info.fg_val; | ||
191 | } | ||
192 | } | ||
193 | pfunc = _grey_pixelfuncs[_grey_info.drawmode]; | ||
194 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1]; | ||
195 | |||
196 | if (fillopt) | ||
197 | _grey_rb->memset(dst, value, x2 - x1 + 1); | ||
198 | else | ||
199 | { | ||
200 | unsigned char *dst_end = dst + x2 - x1; | ||
201 | do | ||
202 | pfunc(dst++); | ||
203 | while (dst <= dst_end); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /* Draw a vertical line (optimised) */ | ||
208 | void grey_vline(int x, int y1, int y2) | ||
209 | { | ||
210 | int y; | ||
211 | unsigned char *dst, *dst_end; | ||
212 | void (*pfunc)(unsigned char *address); | ||
213 | |||
214 | /* direction flip */ | ||
215 | if (y2 < y1) | ||
216 | { | ||
217 | y = y1; | ||
218 | y1 = y2; | ||
219 | y2 = y; | ||
220 | } | ||
221 | |||
222 | /* nothing to draw? */ | ||
223 | if (((unsigned)x >= (unsigned)_grey_info.width) | ||
224 | || (y1 >= _grey_info.height) || (y2 < 0)) | ||
225 | return; | ||
226 | |||
227 | /* clipping */ | ||
228 | if (y1 < 0) | ||
229 | y1 = 0; | ||
230 | if (y2 >= _grey_info.height) | ||
231 | y2 = _grey_info.height - 1; | ||
232 | |||
233 | pfunc = _grey_pixelfuncs[_grey_info.drawmode]; | ||
234 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y1) + x]; | ||
235 | |||
236 | dst_end = dst + _GREY_MULUQ(_grey_info.width, y2 - y1); | ||
237 | do | ||
238 | { | ||
239 | pfunc(dst); | ||
240 | dst += _grey_info.width; | ||
241 | } | ||
242 | while (dst <= dst_end); | ||
243 | } | ||
244 | |||
245 | /* Draw a filled triangle */ | ||
246 | void grey_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3) | ||
247 | { | ||
248 | int x, y; | ||
249 | long fp_x1, fp_x2, fp_dx1, fp_dx2; | ||
250 | |||
251 | /* sort vertices by increasing y value */ | ||
252 | if (y1 > y3) | ||
253 | { | ||
254 | if (y2 < y3) /* y2 < y3 < y1 */ | ||
255 | { | ||
256 | x = x1; x1 = x2; x2 = x3; x3 = x; | ||
257 | y = y1; y1 = y2; y2 = y3; y3 = y; | ||
258 | } | ||
259 | else if (y2 > y1) /* y3 < y1 < y2 */ | ||
260 | { | ||
261 | x = x1; x1 = x3; x3 = x2; x2 = x; | ||
262 | y = y1; y1 = y3; y3 = y2; y2 = y; | ||
263 | } | ||
264 | else /* y3 <= y2 <= y1 */ | ||
265 | { | ||
266 | x = x1; x1 = x3; x3 = x; | ||
267 | y = y1; y1 = y3; y3 = y; | ||
268 | } | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | if (y2 < y1) /* y2 < y1 <= y3 */ | ||
273 | { | ||
274 | x = x1; x1 = x2; x2 = x; | ||
275 | y = y1; y1 = y2; y2 = y; | ||
276 | } | ||
277 | else if (y2 > y3) /* y1 <= y3 < y2 */ | ||
278 | { | ||
279 | x = x2; x2 = x3; x3 = x; | ||
280 | y = y2; y2 = y3; y3 = y; | ||
281 | } | ||
282 | /* else already sorted */ | ||
283 | } | ||
284 | |||
285 | if (y1 < y3) /* draw */ | ||
286 | { | ||
287 | fp_dx1 = ((x3 - x1) << 16) / (y3 - y1); | ||
288 | fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); | ||
289 | |||
290 | if (y1 < y2) /* first part */ | ||
291 | { | ||
292 | fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); | ||
293 | fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); | ||
294 | for (y = y1; y < y2; y++) | ||
295 | { | ||
296 | grey_hline(fp_x1 >> 16, fp_x2 >> 16, y); | ||
297 | fp_x1 += fp_dx1; | ||
298 | fp_x2 += fp_dx2; | ||
299 | } | ||
300 | } | ||
301 | if (y2 < y3) /* second part */ | ||
302 | { | ||
303 | fp_dx2 = ((x3 - x2) << 16) / (y3 - y2); | ||
304 | fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); | ||
305 | for (y = y2; y < y3; y++) | ||
306 | { | ||
307 | grey_hline(fp_x1 >> 16, fp_x2 >> 16, y); | ||
308 | fp_x1 += fp_dx1; | ||
309 | fp_x2 += fp_dx2; | ||
310 | } | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
315 | /* Draw a rectangular box */ | ||
316 | void grey_drawrect(int x, int y, int width, int height) | ||
317 | { | ||
318 | if ((width <= 0) || (height <= 0)) | ||
319 | return; | ||
320 | |||
321 | int x2 = x + width - 1; | ||
322 | int y2 = y + height - 1; | ||
323 | |||
324 | grey_vline(x, y, y2); | ||
325 | grey_vline(x2, y, y2); | ||
326 | grey_hline(x, x2, y); | ||
327 | grey_hline(x, x2, y2); | ||
328 | } | ||
329 | |||
330 | /* Fill a rectangular area */ | ||
331 | void grey_fillrect(int x, int y, int width, int height) | ||
332 | { | ||
333 | int value = 0; | ||
334 | unsigned char *dst, *dst_end; | ||
335 | bool fillopt = false; | ||
336 | void (*pfunc)(unsigned char *address); | ||
337 | |||
338 | /* nothing to draw? */ | ||
339 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | ||
340 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | ||
341 | return; | ||
342 | |||
343 | /* clipping */ | ||
344 | if (x < 0) | ||
345 | { | ||
346 | width += x; | ||
347 | x = 0; | ||
348 | } | ||
349 | if (y < 0) | ||
350 | { | ||
351 | height += y; | ||
352 | y = 0; | ||
353 | } | ||
354 | if (x + width > _grey_info.width) | ||
355 | width = _grey_info.width - x; | ||
356 | if (y + height > _grey_info.height) | ||
357 | height = _grey_info.height - y; | ||
358 | |||
359 | if (_grey_info.drawmode & DRMODE_INVERSEVID) | ||
360 | { | ||
361 | if (_grey_info.drawmode & DRMODE_BG) | ||
362 | { | ||
363 | fillopt = true; | ||
364 | value = _grey_info.bg_val; | ||
365 | } | ||
366 | } | ||
367 | else | ||
368 | { | ||
369 | if (_grey_info.drawmode & DRMODE_FG) | ||
370 | { | ||
371 | fillopt = true; | ||
372 | value = _grey_info.fg_val; | ||
373 | } | ||
374 | } | ||
375 | pfunc = _grey_pixelfuncs[_grey_info.drawmode]; | ||
376 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; | ||
377 | dst_end = dst + _GREY_MULUQ(_grey_info.width, height); | ||
378 | |||
379 | do | ||
380 | { | ||
381 | if (fillopt) | ||
382 | _grey_rb->memset(dst, value, width); | ||
383 | else | ||
384 | { | ||
385 | unsigned char *dst_row = dst; | ||
386 | unsigned char *row_end = dst_row + width; | ||
387 | |||
388 | do | ||
389 | pfunc(dst_row++); | ||
390 | while (dst_row < row_end); | ||
391 | } | ||
392 | dst += _grey_info.width; | ||
393 | } | ||
394 | while (dst < dst_end); | ||
395 | } | ||
396 | |||
397 | /* About Rockbox' internal monochrome bitmap format: | ||
398 | * | ||
399 | * A bitmap contains one bit for every pixel that defines if that pixel is | ||
400 | * foreground (1) or background (0). Bits within a byte are arranged | ||
401 | * vertically, LSB at top. | ||
402 | * The bytes are stored in row-major order, with byte 0 being top left, | ||
403 | * byte 1 2nd from left etc. The first row of bytes defines pixel rows | ||
404 | * 0..7, the second row defines pixel row 8..15 etc. */ | ||
405 | |||
406 | /* Draw a partial monochrome bitmap */ | ||
407 | void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
408 | int stride, int x, int y, int width, int height) | ||
409 | { | ||
410 | const unsigned char *src_end; | ||
411 | unsigned char *dst, *dst_end; | ||
412 | void (*fgfunc)(unsigned char *address); | ||
413 | void (*bgfunc)(unsigned char *address); | ||
414 | |||
415 | /* nothing to draw? */ | ||
416 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | ||
417 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | ||
418 | return; | ||
419 | |||
420 | /* clipping */ | ||
421 | if (x < 0) | ||
422 | { | ||
423 | width += x; | ||
424 | src_x -= x; | ||
425 | x = 0; | ||
426 | } | ||
427 | if (y < 0) | ||
428 | { | ||
429 | height += y; | ||
430 | src_y -= y; | ||
431 | y = 0; | ||
432 | } | ||
433 | if (x + width > _grey_info.width) | ||
434 | width = _grey_info.width - x; | ||
435 | if (y + height > _grey_info.height) | ||
436 | height = _grey_info.height - y; | ||
437 | |||
438 | src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */ | ||
439 | src_y &= 7; | ||
440 | src_end = src + width; | ||
441 | |||
442 | fgfunc = _grey_pixelfuncs[_grey_info.drawmode]; | ||
443 | bgfunc = _grey_pixelfuncs[_grey_info.drawmode ^ DRMODE_INVERSEVID]; | ||
444 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; | ||
445 | |||
446 | do | ||
447 | { | ||
448 | const unsigned char *src_col = src++; | ||
449 | unsigned char *dst_col = dst++; | ||
450 | unsigned data = *src_col >> src_y; | ||
451 | int numbits = 8 - src_y; | ||
452 | |||
453 | dst_end = dst_col + _GREY_MULUQ(_grey_info.width, height); | ||
454 | do | ||
455 | { | ||
456 | if (data & 0x01) | ||
457 | fgfunc(dst_col); | ||
458 | else | ||
459 | bgfunc(dst_col); | ||
460 | |||
461 | dst_col += _grey_info.width; | ||
462 | |||
463 | data >>= 1; | ||
464 | if (--numbits == 0) | ||
465 | { | ||
466 | src_col += stride; | ||
467 | data = *src_col; | ||
468 | numbits = 8; | ||
469 | } | ||
470 | } | ||
471 | while (dst_col < dst_end); | ||
472 | } | ||
473 | while (src < src_end); | ||
474 | } | ||
475 | |||
476 | /* Draw a full monochrome bitmap */ | ||
477 | void grey_mono_bitmap(const unsigned char *src, int x, int y, int width, int height) | ||
478 | { | ||
479 | grey_mono_bitmap_part(src, 0, 0, width, x, y, width, height); | ||
480 | } | ||
481 | |||
482 | /* Draw a partial greyscale bitmap, canonical format */ | ||
483 | void grey_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
484 | int stride, int x, int y, int width, int height) | ||
485 | { | ||
486 | unsigned char *dst, *dst_end; | ||
487 | |||
488 | /* nothing to draw? */ | ||
489 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | ||
490 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | ||
491 | return; | ||
492 | |||
493 | /* clipping */ | ||
494 | if (x < 0) | ||
495 | { | ||
496 | width += x; | ||
497 | src_x -= x; | ||
498 | x = 0; | ||
499 | } | ||
500 | if (y < 0) | ||
501 | { | ||
502 | height += y; | ||
503 | src_y -= y; | ||
504 | y = 0; | ||
505 | } | ||
506 | if (x + width > _grey_info.width) | ||
507 | width = _grey_info.width - x; | ||
508 | if (y + height > _grey_info.height) | ||
509 | height = _grey_info.height - y; | ||
510 | |||
511 | src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ | ||
512 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; | ||
513 | dst_end = dst + _GREY_MULUQ(_grey_info.width, height); | ||
514 | |||
515 | do | ||
516 | { | ||
517 | const unsigned char *src_row = src; | ||
518 | unsigned char *dst_row = dst; | ||
519 | unsigned char *row_end = dst_row + width; | ||
520 | |||
521 | do | ||
522 | *dst_row++ = _grey_info.gvalue[*src_row++]; | ||
523 | while (dst_row < row_end); | ||
524 | |||
525 | src += stride; | ||
526 | dst += _grey_info.width; | ||
527 | } | ||
528 | while (dst < dst_end); | ||
529 | } | ||
530 | |||
531 | /* Draw a full greyscale bitmap, canonical format */ | ||
532 | void grey_gray_bitmap(const unsigned char *src, int x, int y, int width, | ||
533 | int height) | ||
534 | { | ||
535 | grey_gray_bitmap_part(src, 0, 0, width, x, y, width, height); | ||
536 | } | ||
537 | |||
538 | /* Put a string at a given pixel position, skipping first ofs pixel columns */ | ||
539 | void grey_putsxyofs(int x, int y, int ofs, const unsigned char *str) | ||
540 | { | ||
541 | int ch; | ||
542 | struct font* pf = _grey_rb->font_get(_grey_info.curfont); | ||
543 | |||
544 | while ((ch = *str++) != '\0' && x < _grey_info.width) | ||
545 | { | ||
546 | int width; | ||
547 | const unsigned char *bits; | ||
548 | |||
549 | /* check input range */ | ||
550 | if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) | ||
551 | ch = pf->defaultchar; | ||
552 | ch -= pf->firstchar; | ||
553 | |||
554 | /* get proportional width and glyph bits */ | ||
555 | width = pf->width ? pf->width[ch] : pf->maxwidth; | ||
556 | |||
557 | if (ofs > width) | ||
558 | { | ||
559 | ofs -= width; | ||
560 | continue; | ||
561 | } | ||
562 | |||
563 | bits = pf->bits + (pf->offset ? | ||
564 | pf->offset[ch] : (((pf->height + 7) >> 3) * pf->maxwidth * ch)); | ||
565 | |||
566 | grey_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height); | ||
567 | |||
568 | x += width - ofs; | ||
569 | ofs = 0; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | /* Put a string at a given pixel position */ | ||
574 | void grey_putsxy(int x, int y, const unsigned char *str) | ||
575 | { | ||
576 | grey_putsxyofs(x, y, 0, str); | ||
577 | } | ||
578 | |||
579 | /*** Unbuffered drawing functions ***/ | ||
580 | |||
581 | #ifdef SIMULATOR | ||
582 | |||
583 | /* Clear the whole display */ | ||
584 | void grey_ub_clear_display(void) | ||
585 | { | ||
586 | grey_clear_display(); | ||
587 | grey_update(); | ||
588 | } | ||
589 | |||
590 | /* Draw a partial greyscale bitmap, canonical format */ | ||
591 | void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
592 | int stride, int x, int y, int width, int height) | ||
593 | { | ||
594 | grey_gray_bitmap_part(src, src_x, src_y, stride, x, y, width, height); | ||
595 | grey_update_rect(x, y, width, height); | ||
596 | } | ||
597 | |||
598 | #else /* !SIMULATOR */ | ||
599 | |||
600 | /* Clear the greyscale display (sets all pixels to white) */ | ||
601 | void grey_ub_clear_display(void) | ||
602 | { | ||
603 | int value = (_grey_info.drawmode & DRMODE_INVERSEVID) ? | ||
604 | _grey_info.fg_val : _grey_info.bg_val; | ||
605 | unsigned char *dst = &_grey_info.data[0].value; | ||
606 | unsigned char *dst_end = dst + sizeof(struct grey_data) | ||
607 | * _GREY_MULUQ(_grey_info.width, _grey_info.height); | ||
608 | |||
609 | do | ||
610 | { | ||
611 | *dst = value; | ||
612 | dst += sizeof(struct grey_data); | ||
613 | } | ||
614 | while (dst < dst_end); | ||
615 | } | ||
616 | |||
617 | /* Draw a partial greyscale bitmap, canonical format */ | ||
618 | void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
619 | int stride, int x, int y, int width, int height) | ||
620 | { | ||
621 | /* nothing to draw? */ | ||
622 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | ||
623 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | ||
624 | return; | ||
625 | |||
626 | /* clipping */ | ||
627 | if (x < 0) | ||
628 | { | ||
629 | width += x; | ||
630 | src_x -= x; | ||
631 | x = 0; | ||
632 | } | ||
633 | if (y < 0) | ||
634 | { | ||
635 | height += y; | ||
636 | src_y -= y; | ||
637 | y = 0; | ||
638 | } | ||
639 | if (x + width > _grey_info.width) | ||
640 | width = _grey_info.width - x; | ||
641 | if (y + height > _grey_info.height) | ||
642 | height = _grey_info.height - y; | ||
643 | |||
644 | src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ | ||
645 | |||
646 | do | ||
647 | { | ||
648 | #if LCD_PIXELFORMAT == HORIZONTAL_PACKING | ||
649 | int idx = _GREY_MULUQ(_grey_info.width, y) + x; | ||
650 | #else | ||
651 | #if LCD_DEPTH == 1 | ||
652 | int idx = _GREY_MULUQ(_grey_info.width, y & ~7) + (x << 3) + (~y & 7); | ||
653 | #elif LCD_DEPTH == 2 | ||
654 | int idx = _GREY_MULUQ(_grey_info.width, y & ~3) + (x << 2) + (~y & 3); | ||
655 | #endif | ||
656 | #endif /* LCD_PIXELFORMAT */ | ||
657 | unsigned char *dst_row = &_grey_info.data[idx].value; | ||
658 | const unsigned char *src_row = src; | ||
659 | const unsigned char *src_end = src + width; | ||
660 | |||
661 | do | ||
662 | { | ||
663 | *dst_row = _grey_info.gvalue[*src_row++]; | ||
664 | dst_row += _GREY_X_ADVANCE; | ||
665 | } | ||
666 | while (src_row < src_end); | ||
667 | |||
668 | y++; | ||
669 | src += stride; | ||
670 | } | ||
671 | while (--height > 0); | ||
672 | } | ||
673 | |||
674 | #endif /* !SIMULATOR */ | ||
675 | |||
676 | /* Draw a full greyscale bitmap, canonical format */ | ||
677 | void grey_ub_gray_bitmap(const unsigned char *src, int x, int y, int width, | ||
678 | int height) | ||
679 | { | ||
680 | grey_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height); | ||
681 | } | ||