This source file includes following definitions.
- draw_pixel_std
- erase_zebra
- color_to_rawpx
- draw_dblpixel_raw
- color_to_rawpx
- draw_dblpixel_raw
- erase_zebra
- draw_pixel_proc_rotated
- draw_set_draw_proc
- update_draw_proc
- draw_pixel_simple_start
- draw_1pixel_simple
- draw_2pixels_simple
- draw_hline_simple
- draw_set_guard
- draw_test_guard
- draw_set_guard
- draw_test_guard
- draw_init
- draw_suspend
- draw_is_suspended
- draw_restore
- draw_pixel
- draw_or_erase_edge_pixel
- draw_get_pixel
- draw_line
- draw_line_x2
- draw_hline
- draw_vline
- draw_rectangle
- get_cdata
- draw_char
- draw_char
- draw_char_unscaled
- draw_char_scaled
- draw_char_scaled
- draw_string_clipped
- draw_string
- draw_string_justified
- text_dimensions
- draw_text_justified
- draw_string_scaled
- draw_string_scaled
- draw_osd_string
- draw_osd_string
- draw_txt_string
- draw_ellipse
- draw_button
- draw_icon_cmds
- set_palette
- get_script_color
- chdkColorToCanonColor
- user_color
1 #include "platform.h"
2 #include "touchscreen.h"
3 #include "conf.h"
4 #include "font.h"
5 #include "lang.h"
6 #include "gui_draw.h"
7
8 #define GET_FONT_COMPRESSION_MODE 1
9 #include "../lib/font/font_8x16_uni_packed.h"
10 #undef GET_FONT_COMPRESSION_MODE
11
12 #ifdef THUMB_FW
13
14 #define CALC_YUV_LUMA_OPACITY_FOR_COLOR(color,luma,opacity) \
15 { \
16 luma = ((color-1)^0xffffffff)&0xf0; \
17 opacity = (color&0xf)?255:color; \
18 }
19
20 #define CALC_YUV_CHROMA_FOR_COLOR(color,u,v) \
21 { \
22 v = color; \
23 u = (v+1); \
24 if (!(u&2)) \
25 { \
26 u = 128; \
27 v = 128; \
28 } \
29 else \
30 { \
31 u *= 3; \
32 v <<= 3; \
33 } \
34 }
35
36 extern volatile char *opacity_buffer[];
37 extern char* bitmap_buffer[];
38 extern int active_bitmap_buffer;
39
40 #else
41
42 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
43 extern char* bitmap_buffer[];
44 extern int active_bitmap_buffer;
45 #else
46 static char* frame_buffer[2];
47 #endif
48
49 #endif
50
51
52
53
54 int draw_restore_suspend_tick;
55
56 void (*draw_pixel_proc)(unsigned int offset, color cl);
57 void (*draw_pixel_proc_norm)(unsigned int offset, color cl);
58
59
60
61 static void draw_pixel_std(unsigned int offset, color cl)
62 {
63 #ifndef THUMB_FW
64
65 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
66 bitmap_buffer[active_bitmap_buffer][offset] = cl;
67 #else
68 frame_buffer[0][offset] = frame_buffer[1][offset] = cl;
69 #endif
70 #else
71
72
73 unsigned int y;
74 unsigned int o;
75 CALC_YUV_LUMA_OPACITY_FOR_COLOR(cl,y,o);
76 unsigned int u;
77 unsigned int v;
78 CALC_YUV_CHROMA_FOR_COLOR(cl,u,v);
79
80 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
81 int active_buffer_index = active_bitmap_buffer & 1;
82 unsigned char *obu = (unsigned char *)(&opacity_buffer[active_buffer_index][0]);
83 unsigned char *bbu = (unsigned char *)(&bitmap_buffer[active_buffer_index][0]);
84 obu[offset] = o;
85 register unsigned int offs2 = (offset>>1)<<2;
86 if (offset&1)
87 {
88 bbu[offs2+3] = y;
89 }
90 else
91 {
92 bbu[offs2+1] = y;
93 }
94 bbu[offs2+0] = u;
95 bbu[offs2+2] = v;
96 #else
97 opacity_buffer[0][offset] = o;
98 opacity_buffer[1][offset] = o;
99 register unsigned int offs2 = (offset>>1)<<2;
100 if (offset&1)
101 {
102 (bitmap_buffer[0])[offs2+3] = y;
103 (bitmap_buffer[1])[offs2+3] = y;
104 }
105 else
106 {
107 (bitmap_buffer[0])[offs2+1] = y;
108 (bitmap_buffer[1])[offs2+1] = y;
109 }
110 (bitmap_buffer[0])[offs2+0] = u;
111 (bitmap_buffer[1])[offs2+0] = u;
112 (bitmap_buffer[0])[offs2+2] = v;
113 (bitmap_buffer[1])[offs2+2] = v;
114 #endif
115 #endif
116 }
117
118
119
120 #ifdef THUMB_FW
121
122
123
124
125 void erase_zebra()
126 {
127 int x, y;
128 int active_buffer_index = active_bitmap_buffer & 1;
129 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
130 unsigned short *obu = (unsigned short *)(&opacity_buffer[active_buffer_index][0]);
131 unsigned int *bbu = (unsigned int *)(&bitmap_buffer[active_buffer_index][0]);
132 for (y = 0; y < vid_get_viewport_height(); y += 1) {
133 for (x = 0; x < vid_get_viewport_width() / 2; x += 1) {
134 if (obu[x] == 0xfdfd) {
135 obu[x] = 0;
136 bbu[x] = 0x00800080;
137 }
138 }
139 obu += vid_get_viewport_buffer_width_proper() / 2;
140 bbu += vid_get_viewport_buffer_width_proper() / 2;
141 }
142 #else
143 unsigned short *obu0 = (unsigned short *)(&opacity_buffer[active_buffer_index][0]);
144 unsigned int *bbu0 = (unsigned int *)(&bitmap_buffer[active_buffer_index][0]);
145 unsigned short *obu1 = (unsigned short *)(&opacity_buffer[active_buffer_index^1][0]);
146 unsigned int *bbu1 = (unsigned int *)(&bitmap_buffer[active_buffer_index^1][0]);
147 for (y = 0; y < vid_get_viewport_height(); y += 1) {
148 for (x = 0; x < vid_get_viewport_width() / 2; x += 1) {
149 if (obu0[x] == 0xfdfd) {
150 obu0[x] = 0;
151 bbu0[x] = 0x00800080;
152 obu1[x] = 0;
153 bbu1[x] = 0x00800080;
154 }
155 }
156 obu0 += vid_get_viewport_buffer_width_proper() / 2;
157 bbu0 += vid_get_viewport_buffer_width_proper() / 2;
158 obu1 += vid_get_viewport_buffer_width_proper() / 2;
159 bbu1 += vid_get_viewport_buffer_width_proper() / 2;
160 }
161 #endif
162 }
163
164
165
166 unsigned int color_to_rawpx(color cl, unsigned int *op)
167 {
168 unsigned int y,u,v,o;
169 CALC_YUV_CHROMA_FOR_COLOR(cl,u,v);
170 CALC_YUV_LUMA_OPACITY_FOR_COLOR(cl,y,o);
171 if (o == 255) o = 253;
172 if (op) *op = o | (o << 8);
173 return (u&255)+((y&255)<<8)+((v&255)<<16)+(y<<24);
174 }
175
176
177
178
179
180 void draw_dblpixel_raw(unsigned int offset, unsigned int px, unsigned int op)
181 {
182 offset >>= 2;
183 int active_buffer_index = active_bitmap_buffer & 1;
184 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
185 unsigned short *obu = (unsigned short *)(&opacity_buffer[active_buffer_index][0]);
186 unsigned int *bbu = (unsigned int *)(&bitmap_buffer[active_buffer_index][0]);
187 if ((obu[offset] == 0xfdfd) || ((op != 0) && (obu[offset] == 0))) {
188 bbu[offset] = px;
189 obu[offset] = op;
190 }
191 #else
192 unsigned short *obu0 = (unsigned short *)(&opacity_buffer[active_buffer_index][0]);
193 unsigned int *bbu0 = (unsigned int *)(&bitmap_buffer[active_buffer_index][0]);
194 unsigned short *obu1 = (unsigned short *)(&opacity_buffer[active_buffer_index^1][0]);
195 unsigned int *bbu1 = (unsigned int *)(&bitmap_buffer[active_buffer_index^1][0]);
196 if ((obu0[offset] == 0xfdfd) || ((op != 0) && (obu0[offset] == 0))) {
197 bbu0[offset] = px;
198 obu0[offset] = op;
199 bbu1[offset] = px;
200 obu1[offset] = op;
201 }
202 #endif
203 }
204
205 #else
206
207 unsigned int color_to_rawpx(__attribute__ ((unused))color cl, __attribute__ ((unused))unsigned int *op) { return 0; }
208 void draw_dblpixel_raw(__attribute__ ((unused))unsigned int offset, __attribute__ ((unused))unsigned int px, __attribute__ ((unused))unsigned int op) {}
209 void erase_zebra() {}
210 #endif
211
212
213 unsigned int rotate_base;
214
215 void draw_pixel_proc_rotated(unsigned int offset, color cl)
216 {
217 draw_pixel_proc_norm(rotate_base - offset, cl);
218 }
219
220 void draw_set_draw_proc(void (*pixel_proc)(unsigned int offset, color cl))
221 {
222 draw_pixel_proc_norm = (pixel_proc)?pixel_proc:draw_pixel_std;
223 if (conf.rotate_osd)
224 {
225 rotate_base = (camera_screen.height - 1) * camera_screen.buffer_width + ASPECT_XCORRECTION(camera_screen.width) - 1;
226 draw_pixel_proc = draw_pixel_proc_rotated;
227 }
228 else
229 {
230 draw_pixel_proc = draw_pixel_proc_norm;
231 }
232 }
233
234 void update_draw_proc()
235 {
236 draw_set_draw_proc(draw_pixel_proc_norm);
237 }
238
239
240 #ifdef THUMB_FW
241
242
243
244
245 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
246 static unsigned char *current_opacity_buf;
247 static unsigned char *current_bitmap_buf;
248 #endif
249 static unsigned char yuvclr[8];
250
251
252 static void draw_pixel_simple_start(twoColors tc)
253 {
254 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
255 int active_buffer_index = active_bitmap_buffer & 1;
256 current_opacity_buf = (unsigned char *)(&opacity_buffer[active_buffer_index][0]);
257 current_bitmap_buf = (unsigned char *)(&bitmap_buffer[active_buffer_index][0]);
258 #endif
259 color cl;
260 cl = BG_COLOR(tc);
261 CALC_YUV_LUMA_OPACITY_FOR_COLOR(cl,yuvclr[1],yuvclr[3]);
262 CALC_YUV_CHROMA_FOR_COLOR(cl,yuvclr[0],yuvclr[2]);
263 cl = FG_COLOR(tc);
264 CALC_YUV_LUMA_OPACITY_FOR_COLOR(cl,yuvclr[5],yuvclr[7]);
265 CALC_YUV_CHROMA_FOR_COLOR(cl,yuvclr[4],yuvclr[6]);
266 }
267
268
269 static void draw_1pixel_simple(coord x, coord y, int px, int vrepeat)
270 {
271 if ((x < 0) || (y < 0) || (x >= camera_screen.width) || (y+vrepeat >= camera_screen.height)) return;
272 unsigned int offset = y * camera_screen.buffer_width + x;
273 int plus = camera_screen.buffer_width;
274 if (conf.rotate_osd)
275 {
276 offset = rotate_base - offset;
277 plus = -plus;
278 }
279
280 #ifndef CAM_HAS_DISPLAY_REFRESH_FLAG
281 if (!offset) return;
282 #endif
283
284 int fg = px<<2;
285 register unsigned int offs2 = (offset>>1)<<2;
286
287 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
288 unsigned char *obu = current_opacity_buf;
289 unsigned char *bbu = current_bitmap_buf;
290 #endif
291
292 if (offset&1)
293 {
294 while (1)
295 {
296 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
297 obu[offset] = yuvclr[fg+3];
298 bbu[offs2+3] = yuvclr[fg+1];
299 #else
300 opacity_buffer[0][offset] = yuvclr[fg+3];
301 bitmap_buffer[0][offs2+3] = yuvclr[fg+1];
302 opacity_buffer[1][offset] = yuvclr[fg+3];
303 bitmap_buffer[1][offs2+3] = yuvclr[fg+1];
304 #endif
305 if (!vrepeat) return;
306 vrepeat--;
307 offset += plus;
308 offs2 += (plus<<1);
309 }
310 }
311 else
312 {
313 while (1)
314 {
315 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
316 obu[offset] = yuvclr[fg+3];
317 bbu[offs2+1] = yuvclr[fg+1];
318 bbu[offs2+0] = yuvclr[fg];
319 bbu[offs2+2] = yuvclr[fg+2];
320 #else
321 opacity_buffer[0][offset] = yuvclr[fg+3];
322 bitmap_buffer[0][offs2+1] = yuvclr[fg+1];
323 bitmap_buffer[0][offs2+0] = yuvclr[fg];
324 bitmap_buffer[0][offs2+2] = yuvclr[fg+2];
325 opacity_buffer[1][offset] = yuvclr[fg+3];
326 bitmap_buffer[1][offs2+1] = yuvclr[fg+1];
327 bitmap_buffer[1][offs2+0] = yuvclr[fg];
328 bitmap_buffer[1][offs2+2] = yuvclr[fg+2];
329 #endif
330 if (!vrepeat) return;
331 vrepeat--;
332 offset += plus;
333 offs2 += (plus<<1);
334 }
335 }
336
337 }
338
339
340
341 static void draw_2pixels_simple(coord x, coord y, int px, int vrepeat)
342 {
343 if ((x < 0) || (y < 0) || (x+1 >= camera_screen.width) || (y+vrepeat >= camera_screen.height)) return;
344 unsigned int y1, y2;
345 unsigned int offset = (y * camera_screen.buffer_width + x)>>1;
346 int plus;
347 unsigned short co;
348 unsigned int yuv;
349 if (conf.rotate_osd)
350 {
351 offset = (rotate_base>>1) - offset;
352 plus = -(camera_screen.buffer_width>>1);
353 y1 = px&1?4:0;
354 y2 = px&2?4+1:0+1;
355 }
356 else
357 {
358 plus = camera_screen.buffer_width>>1;
359 y1 = px&2?4:0;
360 y2 = px&1?4+1:0+1;
361 }
362
363 #ifndef CAM_HAS_DISPLAY_REFRESH_FLAG
364 if (!offset) return;
365 #endif
366
367 co = yuvclr[y1+3]+(yuvclr[y1+3]<<8);
368 yuv = (*(unsigned int*)(&yuvclr[y1]) & 0xffffff) + (yuvclr[y2]<<24);
369 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
370 unsigned short *obu = (unsigned short *)current_opacity_buf;
371 unsigned int *bbu = (unsigned int *)current_bitmap_buf;
372 #endif
373 while (1)
374 {
375 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
376 obu[offset] = co;
377 bbu[offset] = yuv;
378 #else
379 ((unsigned short *)opacity_buffer[0])[offset] = co;
380 ((unsigned int *)bitmap_buffer[0])[offset] = yuv;
381 ((unsigned short *)opacity_buffer[1])[offset] = co;
382 ((unsigned int *)bitmap_buffer[1])[offset] = yuv;
383 #endif
384 if (!vrepeat) return;
385 vrepeat--;
386 offset += plus;
387 }
388 }
389
390 void draw_hline_simple(coord x, coord y, int len, int px)
391 {
392 if ((y < 0) || (x >= camera_screen.width) || (y >= camera_screen.height)) return;
393 if (x < 0) { len += x; x = 0; }
394 if ((x + len) > camera_screen.width) len = camera_screen.width - x;
395
396 register unsigned int offset = y * camera_screen.buffer_width + (x);
397 if (conf.rotate_osd)
398 {
399 offset = rotate_base - offset - len;
400 }
401
402 #ifndef CAM_HAS_DISPLAY_REFRESH_FLAG
403
404 if (!offset)
405 {
406 offset++;
407 len--;
408 }
409 #endif
410
411 int fg = px<<2;
412 if (offset & 1)
413 {
414 register unsigned int offs2 = (offset>>1)<<2;
415 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
416 unsigned char *obu = current_opacity_buf;
417 unsigned char *bbu = current_bitmap_buf;
418 obu[offset] = yuvclr[fg+3];
419 bbu[offs2+3] = yuvclr[fg+1];
420 #else
421 opacity_buffer[0][offset] = yuvclr[fg+3];
422 bitmap_buffer[0][offs2+3] = yuvclr[fg+1];
423 opacity_buffer[1][offset] = yuvclr[fg+3];
424 bitmap_buffer[1][offs2+3] = yuvclr[fg+1];
425 #endif
426 offset++;
427 len--;
428 }
429 unsigned short co = yuvclr[fg+3]+(yuvclr[fg+3]<<8);
430 unsigned int yuv = (*(unsigned int*)(&yuvclr[fg]) & 0xffffff) + (yuvclr[fg+1]<<24);
431 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
432 unsigned short *obud = (unsigned short *)current_opacity_buf;
433 unsigned int *bbud = (unsigned int *)current_bitmap_buf;
434 for (; len>0; len-=2, offset+=2)
435 {
436 obud[offset>>1] = co;
437 bbud[offset>>1] = yuv;
438 }
439 #else
440 for (; len>0; len-=2, offset+=2)
441 {
442 ((unsigned short *)opacity_buffer[0])[offset>>1] = co;
443 ((unsigned int *)bitmap_buffer[0])[offset>>1] = yuv;
444 ((unsigned short *)opacity_buffer[1])[offset>>1] = co;
445 ((unsigned int *)bitmap_buffer[1])[offset>>1] = yuv;
446 }
447 #endif
448 if (len == -1)
449 {
450 offset--;
451 register unsigned int offs2 = (offset>>1)<<2;
452 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
453 unsigned char *obu = current_opacity_buf;
454 unsigned char *bbu = current_bitmap_buf;
455 obu[offset] = yuvclr[fg+3];
456 bbu[offs2+3] = yuvclr[fg+1];
457 #else
458 opacity_buffer[0][offset] = yuvclr[fg+3];
459 bitmap_buffer[0][offs2+3] = yuvclr[fg+1];
460 opacity_buffer[1][offset] = yuvclr[fg+3];
461 bitmap_buffer[1][offs2+3] = yuvclr[fg+1];
462 #endif
463 }
464 }
465
466
467 #endif
468
469 #ifndef THUMB_FW
470
471 #define GUARD_VAL COLOR_GREY_DK
472
473 void draw_set_guard()
474 {
475 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
476 *((unsigned char*)(bitmap_buffer[0])) = GUARD_VAL;
477 *((unsigned char*)(bitmap_buffer[1])) = GUARD_VAL;
478 #else
479 *((unsigned char*)(frame_buffer[0])) = GUARD_VAL;
480 *((unsigned char*)(frame_buffer[1])) = GUARD_VAL;
481 #endif
482 }
483
484 int draw_test_guard()
485 {
486 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
487 if (*((unsigned char*)(bitmap_buffer[active_bitmap_buffer])) != GUARD_VAL) return 0;
488 #else
489 if (*((unsigned char*)(frame_buffer[0])) != GUARD_VAL) return 0;
490 if (*((unsigned char*)(frame_buffer[1])) != GUARD_VAL) return 0;
491 #endif
492 return 1;
493 }
494
495 #else
496
497 void draw_set_guard()
498 {
499 #ifndef CAM_HAS_DISPLAY_REFRESH_FLAG
500 opacity_buffer[active_bitmap_buffer][0] = 0x42;
501 #endif
502 }
503
504 int draw_test_guard()
505 {
506 #ifdef CAM_HAS_DISPLAY_REFRESH_FLAG
507 extern int display_needs_refresh;
508 if (display_needs_refresh)
509 {
510 display_needs_refresh = 0;
511 return 0;
512 }
513 #else
514 if (opacity_buffer[active_bitmap_buffer][0] != 0x42) return 0;
515 #endif
516 return 1;
517 }
518
519 #endif
520
521 void draw_init()
522 {
523 #ifndef THUMB_FW
524 #ifndef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
525 frame_buffer[0] = vid_get_bitmap_fb();
526 frame_buffer[1] = frame_buffer[0] + camera_screen.buffer_size;
527 #endif
528 #endif
529 draw_set_draw_proc(NULL);
530
531 draw_set_guard();
532 }
533
534
535 void draw_suspend(int ms)
536 {
537 int t=get_tick_count() + ms;
538
539 if(t > draw_restore_suspend_tick) {
540 draw_restore_suspend_tick = t;
541 }
542 }
543
544 int draw_is_suspended(void)
545 {
546 return (draw_restore_suspend_tick > get_tick_count());
547 }
548
549
550 void draw_restore()
551 {
552 if(draw_is_suspended()) {
553 return;
554 }
555 vid_bitmap_refresh();
556
557 draw_set_guard();
558 #ifdef CAM_TOUCHSCREEN_UI
559 redraw_buttons = 1;
560 #endif
561 }
562
563
564 void draw_pixel(coord x, coord y, color cl)
565 {
566
567 if ((x < 0) || (y < 0) || (x >= camera_screen.width) || (y >= camera_screen.height) || ((x == 0) && (y == 0))) return;
568 else
569 {
570 register unsigned int offset = y * camera_screen.buffer_width + ASPECT_XCORRECTION(x);
571 draw_pixel_proc(offset, cl);
572 #if CAM_USES_ASPECT_CORRECTION
573 draw_pixel_proc(offset+1, cl);
574 #endif
575 }
576 }
577
578
579
580
581 void draw_or_erase_edge_pixel(coord px, coord py, color cl, int is_draw)
582 {
583
584 if ((px < 0) || (py < 0) || (px >= camera_screen.width) || (py >= camera_screen.height) || ((px == 0) && (py == 0))) return;
585
586
587 register unsigned int offset = py * camera_screen.buffer_width + ASPECT_XCORRECTION(px);
588
589 #ifndef THUMB_FW
590
591
592 if (!is_draw)
593 {
594 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
595 if (bitmap_buffer[active_bitmap_buffer][offset] != cl) return;
596 #else
597 if (frame_buffer[0][offset] != cl) return;
598 #endif
599 cl = 0;
600 }
601
602
603 draw_pixel_proc_norm(offset, cl);
604 #if CAM_USES_ASPECT_CORRECTION
605 draw_pixel_proc_norm(offset+1, cl);
606 #endif
607
608 #else
609
610
611 if (!is_draw)
612 {
613 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
614 if (opacity_buffer[active_bitmap_buffer&1][offset] != 254) return;
615 #else
616 if (opacity_buffer[0][offset] != 254) return;
617 #endif
618 cl = 0;
619 }
620
621 unsigned int y;
622 unsigned int o;
623 CALC_YUV_LUMA_OPACITY_FOR_COLOR(cl,y,o);
624 unsigned int u;
625 unsigned int v;
626 CALC_YUV_CHROMA_FOR_COLOR(cl,u,v);
627
628 if (o == 255) o = 254;
629
630 register unsigned int offs2 = (offset>>1)<<2;
631
632 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
633 unsigned char *obu = (unsigned char *)(&opacity_buffer[active_bitmap_buffer&1][0]);
634 unsigned char *bbu = (unsigned char *)(&bitmap_buffer[active_bitmap_buffer&1][0]);
635 obu[offset] = o;
636 if (offset&1)
637 {
638 bbu[offs2+3] = y;
639 }
640 else
641 {
642 bbu[offs2+1] = y;
643 }
644 bbu[offs2+0] = u;
645 bbu[offs2+2] = v;
646 #else
647 opacity_buffer[0][offset] = o;
648 opacity_buffer[1][offset] = o;
649 if (offset&1)
650 {
651 (bitmap_buffer[0])[offs2+3] = y;
652 (bitmap_buffer[1])[offs2+3] = y;
653 }
654 else
655 {
656 (bitmap_buffer[0])[offs2+1] = y;
657 (bitmap_buffer[1])[offs2+1] = y;
658 }
659 (bitmap_buffer[0])[offs2+0] = u;
660 (bitmap_buffer[1])[offs2+0] = u;
661 (bitmap_buffer[0])[offs2+2] = v;
662 (bitmap_buffer[1])[offs2+2] = v;
663 #endif
664
665 #endif
666 }
667
668
669 color draw_get_pixel(coord x, coord y)
670 {
671 #ifndef THUMB_FW
672 if ((x < 0) || (y < 0) || (x >= camera_screen.width) || (y >= camera_screen.height)) return 0;
673 if (conf.rotate_osd)
674 {
675 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
676 return bitmap_buffer[0][rotate_base - (y * camera_screen.buffer_width + ASPECT_XCORRECTION(x))];
677 #else
678 return frame_buffer[0][rotate_base - (y * camera_screen.buffer_width + ASPECT_XCORRECTION(x))];
679 #endif
680 }
681 else
682 {
683 #ifdef DRAW_ON_ACTIVE_BITMAP_BUFFER_ONLY
684 return bitmap_buffer[0][y * camera_screen.buffer_width + ASPECT_XCORRECTION(x)];
685 #else
686 return frame_buffer[0][y * camera_screen.buffer_width + ASPECT_XCORRECTION(x)];
687 #endif
688 }
689 #else
690
691 (void)x; (void)y;
692 return 0;
693 #endif
694 }
695
696
697 #define swap(v1, v2) {v1^=v2; v2^=v1; v1^=v2;}
698
699 void draw_line(coord x1, coord y1, coord x2, coord y2, color cl)
700 {
701 unsigned char steep = abs(y2 - y1) > abs(x2 - x1);
702 if (steep)
703 {
704 swap(x1, y1);
705 swap(x2, y2);
706 }
707 if (x1 > x2)
708 {
709 swap(x1, x2);
710 swap(y1, y2);
711 }
712 int deltax = x2 - x1;
713 int deltay = abs(y2 - y1);
714 int error = 0;
715 int y = y1;
716 int ystep = (y1 < y2)?1:-1;
717 int x;
718 for (x=x1; x<=x2; ++x)
719 {
720 if (steep) draw_pixel(y, x, cl);
721 else draw_pixel(x, y, cl);
722 error += deltay;
723 if ((error<<1) >= deltax)
724 {
725 y += ystep;
726 error -= deltax;
727 }
728 }
729 }
730
731 #ifdef THUMB_FW
732
733 void draw_line_x2(coord x1, coord y1, coord x2, coord y2, color cl)
734 {
735 unsigned char steep = abs(y2 - y1) > abs(x2 - x1);
736 if (steep)
737 {
738 swap(x1, y1);
739 swap(x2, y2);
740 }
741 if (x1 > x2)
742 {
743 swap(x1, x2);
744 swap(y1, y2);
745 }
746 int deltax = x2 - x1;
747 int deltay = abs(y2 - y1);
748 int error = 0;
749 int y = y1;
750 int ystep = (y1 < y2)?2:-2;
751 int x;
752 for (x=x1; x<=x2; x+=2)
753 {
754 if (steep) {
755 draw_pixel(y, x, cl);
756 draw_pixel(y+1, x, cl);
757 draw_pixel(y, x+1, cl);
758 draw_pixel(y+1, x+1, cl);
759 } else {
760 draw_pixel(x, y, cl);
761 draw_pixel(x+1, y, cl);
762 draw_pixel(x, y+1, cl);
763 draw_pixel(x+1, y+1, cl);
764 }
765 error += deltay;
766 if ((error<<1) >= deltax)
767 {
768 y += ystep;
769 error -= deltax;
770 }
771 }
772 }
773 #endif
774
775
776 void draw_hline(coord x, coord y, int len, color cl)
777 {
778 if ((y < 0) || (x >= camera_screen.width) || (y >= camera_screen.height)) return;
779 if (x < 0) { len += x; x = 0; }
780 if ((x + len) > camera_screen.width) len = camera_screen.width - x;
781 #ifndef CAM_HAS_DISPLAY_REFRESH_FLAG
782 if (conf.rotate_osd)
783 {
784 if ((y == camera_screen.height-1) && ((x+len) >= camera_screen.width-1)) { x--; len--; }
785 }
786 else
787 {
788 if ((y == 0) && (x == 0)) { x++; len--; }
789 }
790 #endif
791 register unsigned int offset = y * camera_screen.buffer_width + ASPECT_XCORRECTION(x);
792 len = ASPECT_XCORRECTION(len);
793 for (; len>0; len--, offset++)
794 draw_pixel_proc(offset, cl);
795 }
796
797 void draw_vline(coord x, coord y, int len, color cl)
798 {
799 if ((x < 0) || (x >= camera_screen.width) || (y >= camera_screen.height)) return;
800 if (y < 0) { len += y; y = 0; }
801 if ((y + len) > camera_screen.height) len = camera_screen.height - y;
802 for (; len>0; len--, y++)
803 draw_pixel(x, y, cl);
804 }
805
806
807
808
809 void draw_rectangle(coord x1, coord y1, coord x2, coord y2, twoColors cl, int flags)
810 {
811
812 if (x1 > x2)
813 swap(x1, x2);
814 if (y1 > y2)
815 swap(y1, y2);
816
817
818 if ((x2 < 0) || (y2 < 0) || (x1 >= camera_screen.width) || (y1 >= camera_screen.height))
819 return;
820
821 int round = (flags & RECT_ROUND_CORNERS) ? 1 : 0;
822 int thickness;
823 int i;
824
825
826 if (flags & RECT_SHADOW_MASK)
827 {
828 thickness = ((flags & RECT_SHADOW_MASK) >> 4);
829 for (i=1; i<=thickness; i++)
830 {
831 draw_vline(x2+i, y1+1, y2 - y1, COLOR_BLACK);
832 draw_hline(x1+1, y2+i, x2 - x1 + thickness, COLOR_BLACK);
833 }
834 }
835
836
837 thickness = flags & RECT_BORDER_MASK;
838 for (i=0; i<thickness; i++)
839 {
840
841 draw_vline(x1, y1 + round * 2, y2 - y1 - round * 4 + 1, FG_COLOR(cl));
842 draw_vline(x2, y1 + round * 2, y2 - y1 - round * 4 + 1, FG_COLOR(cl));
843 draw_hline(x1 + 1 + round, y1, x2 - x1 - round * 2 - 1, FG_COLOR(cl));
844 draw_hline(x1 + 1 + round, y2, x2 - x1 - round * 2 - 1, FG_COLOR(cl));
845
846 x1++; x2--;
847 y1++; y2--;
848
849 round = 0;
850 }
851
852
853 if (flags & DRAW_FILLED)
854 {
855
856 if (x1 < 0) x1 = 0;
857 if (y1 < 0) y1 = 0;
858 if (x2 >= camera_screen.width) x2 = camera_screen.width - 1;
859 if (y2 >= camera_screen.height) y2 = camera_screen.height - 1;
860
861 coord y;
862 for (y = y1; y <= y2; ++y)
863 draw_hline(x1, y, x2 - x1 + 1, BG_COLOR(cl));
864 }
865 }
866
867
868 #pragma pack(1)
869
870
871 typedef struct {
872 unsigned char skips;
873 } FontData;
874 #pragma pack()
875
876 static unsigned char* get_cdata(unsigned int *offset, unsigned int *size, const char ch)
877 {
878 FontData *f = (FontData*)get_current_font_data(ch);
879
880 *offset = f->skips >> 4;
881 *size = 16 - (f->skips & 0xF);
882 if (*size == *offset)
883 *offset += 1;
884
885 return (unsigned char*)f + sizeof(FontData) - *offset;
886 }
887
888 #ifndef THUMB_FW
889
890 void draw_char(coord x, coord y, const char ch, twoColors cl)
891 {
892 unsigned i, ii;
893
894 unsigned int offset, size;
895 unsigned char *sym = get_cdata(&offset, &size, ch);
896
897
898 for (i=0; i<offset; i++)
899 draw_hline(x, y+i, FONT_WIDTH, BG_COLOR(cl));
900
901
902
903 unsigned j;
904 for (j=i; i<size;)
905 {
906 unsigned int dsym;
907 int rep;
908 #ifdef BUILTIN_FONT_RLE_COMPRESSED
909 dsym = fontdata_lookup[sym[j] & 0x7f];
910 rep = sym[j] & 0x80;
911 #else
912 dsym = sym[j];
913 rep = 0;
914 #endif
915 for (ii=0; ii<FONT_WIDTH; ii++)
916 {
917 draw_pixel(x+ii, y+i, (dsym & (0x80>>ii))? FG_COLOR(cl) : BG_COLOR(cl));
918 }
919 if (rep)
920 {
921 i++;
922 for (ii=0; ii<FONT_WIDTH; ii++)
923 {
924 draw_pixel(x+ii, y+i, (dsym & (0x80>>ii))? FG_COLOR(cl) : BG_COLOR(cl));
925 }
926 }
927 i++;
928 j++;
929 }
930
931
932 for (; i<FONT_HEIGHT; i++)
933 draw_hline(x, y+i, FONT_WIDTH, BG_COLOR(cl));
934 }
935 #endif
936
937 #ifdef THUMB_FW
938
939 void draw_char(coord x, coord y, const char ch, twoColors cl)
940 {
941 unsigned i, ii;
942
943 unsigned int offset, size;
944 unsigned char *sym = get_cdata(&offset, &size, ch);
945
946
947 unsigned int fw = FONT_WIDTH;
948
949 draw_pixel_simple_start(cl);
950
951
952 for (i=0; i<offset; i++)
953 {
954 int j;
955 j = i<<1;
956 draw_hline_simple(x, y+j, fw, 0);
957 draw_hline_simple(x, y+j+1, fw, 0);
958 }
959
960
961
962 unsigned j;
963 for (j=i; i<size;)
964 {
965 unsigned int dsym;
966 int rep;
967 #ifdef BUILTIN_FONT_RLE_COMPRESSED
968 dsym = fontdata_lookup[sym[j] & 0x7f];
969 rep = sym[j] & 0x80;
970 #else
971 dsym = sym[j];
972 rep = 0;
973 #endif
974 {
975
976 ii = 0;
977 ii += (dsym&1)?3:0;
978 ii += (dsym&2)?4:0;
979 ii += (dsym&4)?0x18:0;
980 ii += (dsym&8)?0x60:0;
981 ii += (dsym&16)?0x180:0;
982 ii += (dsym&32)?0x600:0;
983 ii += (dsym&64)?0x1800:0;
984 ii += (dsym&128)?0x2000:0;
985 dsym = ii;
986 }
987
988 while (rep >= 0)
989 {
990 unsigned int px;
991 unsigned int yt = y+(i<<1);
992 ii = 0;
993 if (x&1)
994 {
995 draw_1pixel_simple(x+ii, yt, dsym>>(fw-1), 1);
996 ii++;
997 }
998 for (; ii<fw; ii+=2)
999 {
1000 px = (dsym & ((3<<(fw-2))>>ii))>>(fw-2-ii);
1001 draw_2pixels_simple(x+ii, yt, px, 1);
1002 }
1003 if (x&1)
1004 {
1005 draw_1pixel_simple(x+ii-1, yt, dsym&1, 1);
1006 }
1007 rep -= 0x80;
1008 i++;
1009 }
1010
1011 j++;
1012 }
1013
1014
1015 for (; i<FONT_REAL_HEIGHT; i++)
1016 {
1017 int j;
1018 j = i<<1;
1019 draw_hline_simple(x, y+j, fw, 0);
1020 draw_hline_simple(x, y+j+1, fw, 0);
1021 }
1022 }
1023
1024 void draw_char_unscaled(coord x, coord y, const char ch, twoColors cl)
1025 {
1026 unsigned i, ii;
1027
1028 unsigned int offset, size;
1029 unsigned char *sym = get_cdata(&offset, &size, ch);
1030
1031
1032 unsigned int fw = FONT_REAL_WIDTH;
1033
1034 draw_pixel_simple_start(cl);
1035
1036
1037 for (i=0; i<offset; i++)
1038 {
1039 draw_hline_simple(x, y+i, fw, 0);
1040 }
1041
1042
1043
1044 unsigned j;
1045 for (j=i; i<size;)
1046 {
1047 unsigned int dsym;
1048 int rep;
1049 #ifdef BUILTIN_FONT_RLE_COMPRESSED
1050 dsym = fontdata_lookup[sym[j] & 0x7f];
1051 rep = sym[j] & 0x80;
1052 #else
1053 dsym = sym[j];
1054 rep = 0;
1055 #endif
1056
1057 while (rep >= 0)
1058 {
1059 unsigned int px;
1060 unsigned int yt = y+(i);
1061 ii = 0;
1062 if (x&1)
1063 {
1064 draw_1pixel_simple(x+ii, yt, dsym>>(fw-1), 0);
1065 ii++;
1066 }
1067 for (; ii<fw; ii+=2)
1068 {
1069 px = (dsym & ((3<<(fw-2))>>ii))>>(fw-2-ii);
1070 draw_2pixels_simple(x+ii, yt, px, 0);
1071 }
1072 if (x&1)
1073 {
1074 draw_1pixel_simple(x+ii-1, yt, dsym&1, 0);
1075 }
1076 rep -= 0x80;
1077 i++;
1078 }
1079
1080 j++;
1081 }
1082
1083
1084 for (; i<FONT_REAL_HEIGHT; i++)
1085 {
1086 draw_hline_simple(x, y+i, fw, 0);
1087 }
1088 }
1089
1090 #endif
1091
1092 #ifndef THUMB_FW
1093 void draw_char_scaled(coord x, coord y, const char ch, twoColors cl, int xsize, int ysize)
1094 {
1095 unsigned i, ii;
1096
1097 twoColors clf = MAKE_COLOR(FG_COLOR(cl),FG_COLOR(cl));
1098 twoColors clb = MAKE_COLOR(BG_COLOR(cl),BG_COLOR(cl));
1099
1100 unsigned int offset, size;
1101 unsigned char *sym = get_cdata(&offset, &size, ch);
1102
1103
1104 if (offset > 0)
1105 draw_rectangle(x,y,x+FONT_WIDTH*xsize-1,y+offset*ysize+ysize-1,clb,RECT_BORDER0|DRAW_FILLED);
1106
1107
1108 unsigned j;
1109 for (j=i=offset; i<size;)
1110 {
1111 unsigned int dsym;
1112 int rep;
1113 unsigned int last;
1114 int len;
1115 #ifdef BUILTIN_FONT_RLE_COMPRESSED
1116 dsym = fontdata_lookup[sym[j] & 0x7f];
1117 rep = sym[j] & 0x80;
1118 #else
1119 dsym = sym[j];
1120 rep = 0;
1121 #endif
1122 while (rep >= 0)
1123 {
1124 last = dsym & 0x80;
1125 len = 1;
1126 for (ii=1; ii<FONT_WIDTH; ii++)
1127 {
1128 if (((dsym << ii) & 0x80) != last)
1129 {
1130 draw_rectangle(x+(ii-len)*xsize,y+i*ysize,x+ii*xsize-1,y+i*ysize+ysize-1,(last)?clf:clb,RECT_BORDER0|DRAW_FILLED);
1131 last = (dsym << ii) & 0x80;
1132 len = 1;
1133 }
1134 else
1135 {
1136 len++;
1137 }
1138 }
1139 draw_rectangle(x+(ii-len)*xsize,y+i*ysize,x+ii*xsize-1,y+i*ysize+ysize-1,(last)?clf:clb,RECT_BORDER0|DRAW_FILLED);
1140 i++;
1141 rep -= 0x80;
1142 }
1143 j++;
1144 }
1145
1146
1147 if (i < FONT_HEIGHT)
1148 draw_rectangle(x,y+i*ysize,x+FONT_WIDTH*xsize-1,y+FONT_HEIGHT*ysize+ysize-1,clb,RECT_BORDER0|DRAW_FILLED);
1149 }
1150 #endif
1151
1152 #ifdef THUMB_FW
1153 void draw_char_scaled(coord x, coord y, const char ch, twoColors cl, int xsize, int ysize)
1154 {
1155 unsigned i, ii;
1156
1157 twoColors clf = MAKE_COLOR(FG_COLOR(cl),FG_COLOR(cl));
1158 twoColors clb = MAKE_COLOR(BG_COLOR(cl),BG_COLOR(cl));
1159
1160 unsigned int offset, size;
1161 unsigned char *sym = get_cdata(&offset, &size, ch);
1162
1163 ysize <<= 1;
1164
1165
1166 if (offset > 0)
1167 draw_rectangle(x,y,x+FONT_WIDTH*xsize-1,y+offset*ysize+ysize-1,clb,RECT_BORDER0|DRAW_FILLED);
1168
1169
1170 unsigned j;
1171 for (j=i=offset; i<size;)
1172 {
1173 unsigned int dsym;
1174 int rep;
1175 unsigned int last;
1176 int len;
1177 unsigned int lastmask = 1 << (FONT_WIDTH-1);
1178 #ifdef BUILTIN_FONT_RLE_COMPRESSED
1179 dsym = fontdata_lookup[sym[j] & 0x7f];
1180 rep = sym[j] & 0x80;
1181 #else
1182 dsym = sym[j];
1183 rep = 0;
1184 #endif
1185 {
1186
1187 ii = 0;
1188 ii += (dsym&1)?3:0;
1189 ii += (dsym&2)?4:0;
1190 ii += (dsym&4)?0x18:0;
1191 ii += (dsym&8)?0x60:0;
1192 ii += (dsym&16)?0x180:0;
1193 ii += (dsym&32)?0x600:0;
1194 ii += (dsym&64)?0x1800:0;
1195 ii += (dsym&128)?0x2000:0;
1196 dsym = ii;
1197 }
1198 while (rep >= 0)
1199 {
1200 last = dsym & lastmask;
1201 len = 1;
1202 for (ii=1; ii<FONT_WIDTH; ii++)
1203 {
1204 if (((dsym << ii) & lastmask) != last)
1205 {
1206 draw_rectangle(x+(ii-len)*xsize,y+i*ysize,x+ii*xsize-1,y+i*ysize+ysize-1,(last)?clf:clb,RECT_BORDER0|DRAW_FILLED);
1207 last = (dsym << ii) & lastmask;
1208 len = 1;
1209 }
1210 else
1211 {
1212 len++;
1213 }
1214 }
1215 draw_rectangle(x+(ii-len)*xsize,y+i*ysize,x+ii*xsize-1,y+i*ysize+ysize-1,(last)?clf:clb,RECT_BORDER0|DRAW_FILLED);
1216 i++;
1217 rep -= 0x80;
1218 }
1219 j++;
1220 }
1221
1222
1223 if (i < FONT_REAL_HEIGHT)
1224 draw_rectangle(x,y+i*ysize,x+FONT_WIDTH*xsize-1,y+FONT_REAL_HEIGHT*ysize+ysize-1,clb,RECT_BORDER0|DRAW_FILLED);
1225 }
1226 #endif
1227
1228
1229
1230
1231 int draw_string_clipped(coord x, coord y, const char *s, twoColors cl, int max_width)
1232 {
1233 while (*s && (*s != '\n') && (max_width >= FONT_WIDTH))
1234 {
1235 draw_char(x, y, *s, cl);
1236 s++;
1237 max_width -= FONT_WIDTH;
1238 x += FONT_WIDTH;
1239 if ((x>=camera_screen.width) && (*s))
1240 {
1241 draw_char(x-FONT_WIDTH,y, '>', cl);
1242 break;
1243 }
1244 }
1245 return x;
1246 }
1247
1248
1249 int draw_string(coord x, coord y, const char *s, twoColors cl)
1250 {
1251 return draw_string_clipped(x, y, s, cl, camera_screen.width);
1252 }
1253
1254
1255
1256
1257
1258
1259 int draw_string_justified(coord x, coord y, const char *s, twoColors cl, int xo, int max_width, int justification)
1260 {
1261
1262 const char *e = strchr(s, '\n');
1263 int l;
1264 if (e)
1265 l = (e - s) * FONT_WIDTH;
1266 else
1267 l = strlen(s) * FONT_WIDTH;
1268 if (l > max_width) l = max_width;
1269
1270
1271 switch (justification & 0xF)
1272 {
1273 case TEXT_RIGHT:
1274 xo = (max_width - l);
1275 break;
1276 case TEXT_CENTER:
1277 xo = ((max_width - l) >> 1);
1278 break;
1279 }
1280
1281
1282 if ((justification & TEXT_FILL) && (xo > 0))
1283 draw_rectangle(x, y, x+xo-1, y+FONT_HEIGHT-1, cl, RECT_BORDER0|DRAW_FILLED);
1284
1285
1286 l = draw_string_clipped(x+xo, y, s, cl, max_width - xo) - x;
1287
1288
1289 if ((justification & TEXT_FILL) && (l < max_width))
1290 draw_rectangle(x+l, y, x+max_width-1, y+FONT_HEIGHT-1, cl, RECT_BORDER0|DRAW_FILLED);
1291
1292
1293 return x+xo;
1294 }
1295
1296
1297
1298
1299
1300
1301 int text_dimensions(const char *s, int width, int max_chars, int *max_lines)
1302 {
1303 int l = 0, n;
1304 while (s && *s && (l < *max_lines))
1305 {
1306 const char *e = strchr(s, '\n');
1307 if (e)
1308 {
1309 n = e - s;
1310 e++;
1311 }
1312 else
1313 {
1314 n = strlen(s);
1315 }
1316
1317 if (n > width) width = n;
1318
1319 s = e;
1320 l++;
1321 }
1322 *max_lines = l;
1323 if (width > max_chars) width = max_chars;
1324 return width;
1325 }
1326
1327
1328
1329
1330
1331
1332 int draw_text_justified(coord x, coord y, const char *s, twoColors cl, int max_chars, int max_lines, int justification)
1333 {
1334 int rx = 0;
1335 while (s && *s && (max_lines > 0))
1336 {
1337 const char *e = strchr(s, '\n');
1338 if (e) e++;
1339
1340 rx = draw_string_justified(x, y, s, cl, 0, max_chars*FONT_WIDTH, justification);
1341
1342 s = e;
1343 y += FONT_HEIGHT;
1344 max_lines--;
1345 }
1346 return rx;
1347 }
1348
1349
1350 #ifndef THUMB_FW
1351 void draw_string_scaled(coord x, coord y, const char *s, twoColors cl, int xsize, int ysize)
1352 {
1353 while (*s && (*s != '\n'))
1354 {
1355 draw_char_scaled(x, y, *s, cl, xsize, ysize);
1356 s++;
1357 x+=FONT_WIDTH*xsize;
1358 if ((x>=camera_screen.width) && (*s))
1359 {
1360 draw_char_scaled(x-FONT_WIDTH*xsize,y, '>', cl, xsize, ysize);
1361 break;
1362 }
1363 }
1364 }
1365 #endif
1366
1367 #ifdef THUMB_FW
1368 void draw_string_scaled(coord x, coord y, const char *s, twoColors cl, int xsize, int ysize)
1369 {
1370 if ((xsize==0) || (ysize==0))
1371 {
1372 while (*s && (*s != '\n'))
1373 {
1374 draw_char_unscaled(x, y, *s, cl);
1375 s++;
1376 x+=FONT_REAL_WIDTH;
1377 if ((x>=camera_screen.width) && (*s))
1378 {
1379 draw_char_unscaled(x-FONT_REAL_WIDTH,y, '>', cl);
1380 break;
1381 }
1382 }
1383 }
1384 else
1385 {
1386 while (*s && (*s != '\n'))
1387 {
1388 draw_char_scaled(x, y, *s, cl, xsize, ysize);
1389 s++;
1390 x+=FONT_WIDTH*xsize;
1391 if ((x>=camera_screen.width) && (*s))
1392 {
1393 draw_char_scaled(x-FONT_WIDTH*xsize,y, '>', cl, xsize, ysize);
1394 break;
1395 }
1396 }
1397 }
1398 }
1399 #endif
1400
1401
1402 #ifndef THUMB_FW
1403 void draw_osd_string(OSD_pos pos, int xo, int yo, char *s, twoColors c, OSD_scale scale)
1404 {
1405 if ((scale.x == 0) || (scale.y == 0) || ((scale.x == 1) && (scale.y == 1)))
1406 draw_string(pos.x+xo, pos.y+yo, s, c);
1407 else
1408 draw_string_scaled(pos.x+(xo*scale.x), pos.y+(yo*scale.y), s, c, scale.x, scale.y);
1409 }
1410 #endif
1411
1412 #ifdef THUMB_FW
1413 void draw_osd_string(OSD_pos pos, int xo, int yo, char *s, twoColors c, OSD_scale scale)
1414 {
1415 if ((scale.x == 1) && (scale.y == 1))
1416 {
1417 draw_string(pos.x+xo, pos.y+yo, s, c);
1418 }
1419 else if ((scale.x == 0) || (scale.y == 0))
1420 {
1421 draw_string_scaled(pos.x+(xo>>1), pos.y+(yo>>1), s, c, scale.x, scale.y);
1422 }
1423 else
1424 {
1425 draw_string_scaled(pos.x+(xo*scale.x), pos.y+(yo*scale.y), s, c, scale.x, scale.y);
1426 }
1427 }
1428 #endif
1429
1430
1431
1432
1433 void draw_txt_string(coord col, coord row, const char *str, twoColors cl)
1434 {
1435 draw_string(col*FONT_WIDTH, row*FONT_HEIGHT, str, cl);
1436 }
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468 void draw_ellipse(coord CX, coord CY, unsigned int XRadius, unsigned int YRadius, color cl, int flags)
1469 {
1470
1471 int X, Y;
1472 int XChange, YChange;
1473 int EllipseError;
1474 int TwoASquare, TwoBSquare;
1475 int StoppingX, StoppingY;
1476 TwoASquare = 2*XRadius*XRadius;
1477 TwoBSquare = 2*YRadius*YRadius;
1478 X = XRadius;
1479 Y = 0;
1480 XChange = YRadius*YRadius*(1-2*XRadius);
1481 YChange = XRadius*XRadius;
1482 EllipseError = 0;
1483 StoppingX = TwoBSquare*XRadius;
1484 StoppingY = 0;
1485 while ( StoppingX >= StoppingY )
1486 {
1487 if (flags & DRAW_FILLED)
1488 {
1489 draw_hline(CX-X,CY-Y,X*2+1,cl);
1490 draw_hline(CX-X,CY+Y,X*2+1,cl);
1491 }
1492 else
1493 {
1494 draw_pixel(CX-X,CY-Y,cl);
1495 draw_pixel(CX-X,CY+Y,cl);
1496 draw_pixel(CX+X,CY-Y,cl);
1497 draw_pixel(CX+X,CY+Y,cl);
1498 }
1499 Y++;
1500 StoppingY += TwoASquare;
1501 EllipseError += YChange;
1502 YChange += TwoASquare;
1503 if ((2*EllipseError + XChange) > 0 )
1504 {
1505 X--;
1506 StoppingX -= TwoBSquare;
1507 EllipseError += XChange;
1508 XChange += TwoBSquare;
1509 }
1510 }
1511 X = 0;
1512 Y = YRadius;
1513 XChange = YRadius*YRadius;
1514 YChange = XRadius*XRadius*(1-2*YRadius);
1515 EllipseError = 0;
1516 StoppingX = 0;
1517 StoppingY = TwoASquare*YRadius;
1518 int lastY = Y + 1;
1519 while ( StoppingX <= StoppingY )
1520 {
1521 if (flags & DRAW_FILLED)
1522 {
1523
1524 if (lastY != Y)
1525 {
1526 draw_hline(CX-X,CY-Y,X*2+1,cl);
1527 draw_hline(CX-X,CY+Y,X*2+1,cl);
1528 lastY = Y;
1529 }
1530 }
1531 else
1532 {
1533 draw_pixel(CX-X,CY-Y,cl);
1534 draw_pixel(CX-X,CY+Y,cl);
1535 draw_pixel(CX+X,CY-Y,cl);
1536 draw_pixel(CX+X,CY+Y,cl);
1537 }
1538 X++;
1539 StoppingX += TwoBSquare;
1540 EllipseError += XChange;
1541 XChange += TwoBSquare;
1542 if ((2*EllipseError + YChange) > 0 )
1543 {
1544 Y--;
1545 StoppingY -= TwoASquare;
1546 EllipseError += YChange;
1547 YChange += TwoASquare;
1548 }
1549 }
1550 }
1551
1552
1553
1554 void draw_button(int x, int y, int w, int str_id, int active)
1555 {
1556 twoColors cl = MAKE_COLOR((active) ? COLOR_RED : COLOR_BLACK, COLOR_WHITE);
1557 w = w * FONT_WIDTH;
1558
1559 draw_rectangle(x-2, y-2, x+w+2, y+FONT_HEIGHT+2, cl, RECT_BORDER1|DRAW_FILLED|RECT_SHADOW1);
1560 draw_string(x+((w-(strlen(lang_str(str_id))*FONT_WIDTH))>>1), y, lang_str(str_id), cl);
1561 }
1562
1563
1564
1565
1566 void draw_icon_cmds(coord x, coord y, icon_cmd *cmds)
1567 {
1568 int x1, y1, x2, y2;
1569 #ifdef THUMB_FW
1570 int thickness = RECT_BORDER2;
1571 #else
1572 int thickness = RECT_BORDER1;
1573 #endif
1574 while (1)
1575 {
1576 #ifdef THUMB_FW
1577 x1 = cmds->x1<<1;
1578 y1 = cmds->y1<<1;
1579 x2 = cmds->x2<<1;
1580 y2 = cmds->y2<<1;
1581 #else
1582 x1 = cmds->x1;
1583 y1 = cmds->y1;
1584 x2 = cmds->x2;
1585 y2 = cmds->y2;
1586 #endif
1587 color cf = chdk_colors[cmds->cf];
1588 color cb = chdk_colors[cmds->cb];
1589 switch (cmds->action)
1590 {
1591 default:
1592 case IA_END:
1593 return;
1594 case IA_HLINE:
1595 draw_hline(x+x1, y+y1, x2, cb);
1596 #ifdef THUMB_FW
1597 draw_hline(x+x1, y+y1+1, x2, cb);
1598 #endif
1599 break;
1600 case IA_VLINE:
1601 draw_vline(x+x1, y+y1, y2, cb);
1602 #ifdef THUMB_FW
1603 draw_vline(x+x1+1, y+y1, y2, cb);
1604 #endif
1605 break;
1606 case IA_LINE:
1607 #ifdef THUMB_FW
1608 draw_line_x2(x+x1, y+y1, x+x2, y+y2, cb);
1609 #else
1610 draw_line(x+x1, y+y1, x+x2, y+y2, cb);
1611 #endif
1612 break;
1613 case IA_RECT:
1614 #ifdef THUMB_FW
1615 draw_rectangle(x+x1, y+y1, x+x2+1, y+y2+1, MAKE_COLOR(cb,cf), thickness);
1616 #else
1617 draw_rectangle(x+x1, y+y1, x+x2, y+y2, MAKE_COLOR(cb,cf), thickness);
1618 #endif
1619 break;
1620 case IA_FILLED_RECT:
1621 #ifdef THUMB_FW
1622 draw_rectangle(x+x1, y+y1, x+x2+1, y+y2+1, MAKE_COLOR(cb,cf), thickness|DRAW_FILLED);
1623 #else
1624 draw_rectangle(x+x1, y+y1, x+x2, y+y2, MAKE_COLOR(cb,cf), thickness|DRAW_FILLED);
1625 #endif
1626 break;
1627 case IA_ROUND_RECT:
1628 #ifdef THUMB_FW
1629 draw_rectangle(x+x1, y+y1, x+x2+1, y+y2+1, MAKE_COLOR(cb,cf), thickness|RECT_ROUND_CORNERS);
1630 #else
1631 draw_rectangle(x+x1, y+y1, x+x2, y+y2, MAKE_COLOR(cb,cf), thickness|RECT_ROUND_CORNERS);
1632 #endif
1633 break;
1634 case IA_FILLED_ROUND_RECT:
1635 #ifdef THUMB_FW
1636 draw_rectangle(x+x1, y+y1, x+x2+1, y+y2+1, MAKE_COLOR(cb,cf), thickness|DRAW_FILLED|RECT_ROUND_CORNERS);
1637 #else
1638 draw_rectangle(x+x1, y+y1, x+x2, y+y2, MAKE_COLOR(cb,cf), thickness|DRAW_FILLED|RECT_ROUND_CORNERS);
1639 #endif
1640 break;
1641 }
1642 cmds++;
1643 }
1644 }
1645
1646
1647
1648 extern unsigned char ply_colors[];
1649 extern unsigned char rec_colors[];
1650
1651 unsigned char *chdk_colors = ply_colors;
1652
1653 void set_palette()
1654 {
1655 #ifndef THUMB_FW
1656 if (camera_info.state.mode_rec)
1657 chdk_colors = rec_colors;
1658 else
1659 chdk_colors = ply_colors;
1660 #endif
1661 }
1662
1663 color get_script_color(int cl)
1664 {
1665 if (cl < 256)
1666 return cl;
1667 else
1668 return chdk_colors[cl-256];
1669 }
1670
1671
1672 color chdkColorToCanonColor(chdkColor col)
1673 {
1674 if (col.type)
1675 return chdk_colors[col.col];
1676 return col.col;
1677 }
1678
1679 twoColors user_color(confColor cc)
1680 {
1681 color fg = chdkColorToCanonColor(cc.fg);
1682 color bg = chdkColorToCanonColor(cc.bg);
1683
1684 return MAKE_COLOR(bg,fg);
1685 }
1686
1687