source: branches/reyalp-ptp-live/core/gui_draw.c @ 1813

Revision 1813, 16.3 KB checked in by reyalp, 13 months ago (diff)

updating live view branch with trunk changes up to r1762

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6#include "font.h"
7#include "gui_draw.h"
8
9//-------------------------------------------------------------------
10static char*    frame_buffer[2];
11void            (*draw_pixel_proc)(unsigned int offset, color cl);
12
13//-------------------------------------------------------------------
14static void draw_pixel_std(unsigned int offset, color cl) {
15    frame_buffer[0][offset] = frame_buffer[1][offset] = cl & 0xff;
16}
17
18//-------------------------------------------------------------------
19void draw_set_draw_proc(void (*pixel_proc)(unsigned int offset, color cl)) {
20    draw_pixel_proc = (pixel_proc)?pixel_proc:draw_pixel_std;
21}
22
23//-------------------------------------------------------------------
24#ifdef CAM_DETECT_SCREEN_ERASE
25
26#define GUARD_VAL   SCREEN_COLOR
27
28void draw_set_guard()
29{
30    *((unsigned char*)(frame_buffer[0])) = GUARD_VAL;
31    *((unsigned char*)(frame_buffer[1])) = GUARD_VAL;
32}
33
34int draw_test_guard()
35{
36    if (*((unsigned char*)(frame_buffer[0])) != GUARD_VAL) return 0;
37    if (*((unsigned char*)(frame_buffer[1])) != GUARD_VAL) return 0;
38    return 1;
39}
40
41// Test a pixel value in both frame buffers, returns 0 if either doesn't match or co-ords out of range
42int draw_test_pixel(coord x, coord y, color c)
43{
44    if (x >= camera_screen.width || y >= camera_screen.height) return 0;
45    return (frame_buffer[0][y * camera_screen.buffer_width + ASPECT_XCORRECTION(x)] == c) &&
46           (frame_buffer[1][y * camera_screen.buffer_width + ASPECT_XCORRECTION(x)] == c);
47}
48
49#endif
50
51//-------------------------------------------------------------------
52void draw_init() {
53    register int i;
54
55    frame_buffer[0] = vid_get_bitmap_fb();
56    frame_buffer[1] = frame_buffer[0] + camera_screen.buffer_size;
57    draw_set_draw_proc(NULL);
58
59#ifdef CAM_DETECT_SCREEN_ERASE
60    draw_set_guard();
61#endif
62}
63
64//-------------------------------------------------------------------
65void draw_pixel(coord x, coord y, color cl) {
66    if (x >= camera_screen.width || y >= camera_screen.height) return;
67    else {
68        register unsigned int offset = y * camera_screen.buffer_width + ASPECT_XCORRECTION(x);
69        draw_pixel_proc(offset,   cl);
70#if CAM_USES_ASPECT_CORRECTION
71        draw_pixel_proc(offset+1, cl);  // Draw second pixel if screen scaling is needed
72#endif
73   }
74}
75
76//-------------------------------------------------------------------
77color draw_get_pixel(coord x, coord y) {
78    if (x >= camera_screen.width || y >= camera_screen.height) return 0;
79    return frame_buffer[0][y * camera_screen.buffer_width + ASPECT_XCORRECTION(x) ];
80}
81
82//-------------------------------------------------------------------
83#define swap(v1, v2)   {v1^=v2; v2^=v1; v1^=v2;}
84//-------------------------------------------------------------------
85void draw_line(coord x1, coord y1, coord x2, coord y2, color cl) {
86     unsigned char steep = abs(y2 - y1) > abs(x2 - x1);
87     if (steep) {
88         swap(x1, y1);
89         swap(x2, y2);
90     }
91     if (x1 > x2) {
92         swap(x1, x2);
93         swap(y1, y2);
94     }
95     int deltax = x2 - x1;
96     int deltay = abs(y2 - y1);
97     int error = 0;
98     int y = y1;
99     int ystep = (y1 < y2)?1:-1;
100     int x;
101     for (x=x1; x<=x2; ++x) {
102         if (steep) draw_pixel(y, x, cl);
103         else draw_pixel(x, y, cl);
104         error += deltay;
105         if ((error<<1) >= deltax) {
106             y += ystep;
107             error -= deltax;
108         }
109     }
110}
111//-------------------------------------------------------------------
112void draw_hline(coord x, coord y, int len, color cl)
113{
114    if (x >= camera_screen.width || y >= camera_screen.height) return;
115    if (x < 0) { len += x; x = 0; }
116    if ((x + len) > camera_screen.width) len = camera_screen.width - x;
117    register unsigned int offset = y * camera_screen.buffer_width + ASPECT_XCORRECTION(x);
118    len = ASPECT_XCORRECTION(len);      // Scale the line length if needed
119    for (; len>0; len--, offset++)
120        draw_pixel_proc(offset, cl);
121}
122
123void draw_vline(coord x, coord y, int len, color cl)
124{
125    if ((x < 0) || (x >= camera_screen.width) || (y >= camera_screen.height)) return;
126    if (y < 0) { len += y; y = 0; }
127    if ((y + len) > camera_screen.height) len = camera_screen.height - y;
128    for (; len>0; len--, y++)
129      draw_pixel(x, y, cl);
130}
131//-------------------------------------------------------------------
132
133// Local variables set up by draw_rectangle, and used in fill_rect
134static unsigned int xMin, yMin, xMax, yMax;
135
136static void draw_rectangle(coord x1, coord y1, coord x2, coord y2, color cl, int round)
137{
138    register unsigned int x, y;
139
140    if (x1>x2) {
141        xMax=x1; xMin=x2;
142    } else {
143        xMin=x1; xMax=x2;
144    }
145    if (y1>y2) {
146        yMax=y1; yMin=y2;
147    } else {
148        yMin=y1; yMax=y2;
149    }
150    if (xMax>=camera_screen.width) xMax=camera_screen.width-1;
151    if (xMin>=camera_screen.width) xMin=camera_screen.width-1;
152    if (yMax>=camera_screen.height) yMax=camera_screen.height-1;
153    if (yMin>=camera_screen.height) yMin=camera_screen.height-1;
154
155    for (y=yMin+(round<<1); y<=yMax-(round<<1); ++y)
156    {
157      draw_pixel(xMin, y, cl);
158      draw_pixel(xMax, y, cl);
159    }
160
161    draw_hline(xMin+1+round, yMin, (xMax-1-round) - (xMin+1+round) + 1, cl);
162    draw_hline(xMin+1+round, yMax, (xMax-1-round) - (xMin+1+round) + 1, cl);
163}
164
165//-------------------------------------------------------------------
166void draw_rect(coord x1, coord y1, coord x2, coord y2, color cl) {
167    draw_rectangle(x1,y1,x2,y2,cl&0xff,0);
168}
169
170void draw_rect_thick(coord x1, coord y1, coord x2, coord y2, color cl, int thickness) {
171    int i;
172    cl = cl & 0xff;
173    for (i=0; i<thickness; i++)
174    {
175        draw_rectangle(x1+i,y1+i,x2-i,y2-i,cl,0);
176    }
177}
178
179void draw_rect_shadow(coord x1, coord y1, coord x2, coord y2, color cl, int thickness) {
180    int i;
181    cl = cl & 0xff;
182    for (i=0; i<thickness; i++)
183    {
184        draw_rectangle(x1+i,y1+i,x2+i,y2+i,cl,0);
185    }
186}
187//-------------------------------------------------------------------
188void draw_round_rect(coord x1, coord y1, coord x2, coord y2, color cl) {
189    draw_rectangle(x1,y1,x2,y2,cl&0xff,1);
190}
191
192void draw_round_rect_thick(coord x1, coord y1, coord x2, coord y2, color cl, int thickness) {
193    int i;
194    cl = cl & 0xff;
195    draw_rectangle(x1,y1,x2,y2,cl,1);
196    for (i=1; i<thickness; i++)
197    {
198        draw_rectangle(x1+i,y1+i,x2-i,y2-i,cl,0);
199    }
200}
201//-------------------------------------------------------------------
202static void fill_rect(color cl) {
203    register unsigned int x, y;
204
205    cl = BG_COLOR(cl);
206    for (y=yMin+1; y<=yMax-1; ++y)
207    {
208        draw_hline(xMin+1, y, (xMax-1) - (xMin+1) + 1, cl);
209    }
210}
211//-------------------------------------------------------------------
212void draw_filled_rect(coord x1, coord y1, coord x2, coord y2, color cl) {
213    draw_rect(x1, y1, x2, y2, cl);
214    fill_rect(cl);
215}
216
217void draw_filled_rect_thick(coord x1, coord y1, coord x2, coord y2, color cl, int thickness) {
218    draw_rect_thick(x1, y1, x2, y2, cl, thickness);
219    fill_rect(cl);
220}
221//-------------------------------------------------------------------
222void draw_filled_round_rect(coord x1, coord y1, coord x2, coord y2, color cl) {
223    draw_round_rect(x1, y1, x2, y2, cl);
224    fill_rect(cl);
225}
226
227void draw_filled_round_rect_thick(coord x1, coord y1, coord x2, coord y2, color cl, int thickness) {
228    draw_round_rect_thick(x1, y1, x2, y2, cl, thickness);
229    fill_rect(cl);
230}
231//-------------------------------------------------------------------
232void draw_char(coord x, coord y, const char ch, color cl)
233{
234    FontData *f = (FontData*)get_current_font_data(ch);
235    const unsigned char *sym = (unsigned char*)f + sizeof(FontData) - f->offset;
236    int i, ii;
237
238    // First draw blank lines at top
239    for (i=0; i<f->offset; i++)
240        draw_hline(x, y+i, FONT_WIDTH, BG_COLOR(cl));
241    // Now draw character data
242    for (; i<f->offset+f->size; i++)
243    {
244            for (ii=0; ii<FONT_WIDTH; ii++)
245        {
246            draw_pixel(x+ii ,y+i, (sym[i] & (0x80>>ii))? FG_COLOR(cl) : BG_COLOR(cl));
247            }
248    }
249    // Last draw blank lines at bottom
250    for (; i<FONT_HEIGHT; i++)
251        draw_hline(x, y+i, FONT_WIDTH, BG_COLOR(cl));
252}
253
254//-------------------------------------------------------------------
255void draw_string(coord x, coord y, const char *s, color cl) {
256    while(*s)
257    {
258            draw_char(x, y, *s, cl);
259            s++;
260            x+=FONT_WIDTH;
261            if ((x>=camera_screen.width) && (*s))
262        {
263                draw_char(x-FONT_WIDTH,y, '>', cl);
264                break;
265            }
266    }
267}
268
269//-------------------------------------------------------------------
270void draw_txt_rect(coord col, coord row, unsigned int length, unsigned int height, color cl) {
271    draw_rect(col*FONT_WIDTH, row*FONT_HEIGHT, (col+length)*FONT_WIDTH-1, (row+height)*FONT_HEIGHT-1, cl);
272}
273
274//-------------------------------------------------------------------
275void draw_txt_rect_exp(coord col, coord row, unsigned int length, unsigned int height, unsigned int exp, color cl) {
276    draw_rect(col*FONT_WIDTH-exp, row*FONT_HEIGHT-exp, (col+length)*FONT_WIDTH-1+exp, (row+height)*FONT_HEIGHT-1+exp, cl);
277}
278
279//-------------------------------------------------------------------
280void draw_txt_filled_rect(coord col, coord row, unsigned int length, unsigned int height, color cl) {
281    draw_filled_rect(col*FONT_WIDTH, row*FONT_HEIGHT, (col+length)*FONT_WIDTH-1, (row+height)*FONT_HEIGHT-1, cl);
282}
283
284//-------------------------------------------------------------------
285void draw_txt_filled_rect_exp(coord col, coord row, unsigned int length, unsigned int height, unsigned int exp, color cl) {
286    draw_filled_rect(col*FONT_WIDTH-exp, row*FONT_HEIGHT-exp, (col+length)*FONT_WIDTH-1+exp, (row+height)*FONT_HEIGHT-1+exp, cl);
287}
288
289//-------------------------------------------------------------------
290void draw_txt_string(coord col, coord row, const char *str, color cl) {
291    draw_string(col*FONT_WIDTH, row*FONT_HEIGHT, str, cl);
292}
293
294//-------------------------------------------------------------------
295void draw_txt_char(coord col, coord row, const char ch, color cl) {
296    draw_char(col*FONT_WIDTH, row*FONT_HEIGHT, ch, cl);
297}
298
299//-------------------------------------------------------------------
300void draw_clear() {
301    memset(frame_buffer[0], COLOR_TRANSPARENT, camera_screen.buffer_size*2);
302}
303
304// Restore CANON_OSD
305//-------------------------------------------------------------------
306void draw_restore() {
307    vid_bitmap_refresh();
308
309#ifdef CAM_DETECT_SCREEN_ERASE
310    draw_set_guard();
311#ifdef CAM_TOUCHSCREEN_UI
312    extern int redraw_buttons;
313    redraw_buttons = 1;
314#endif
315#endif
316}
317
318//-------------------------------------------------------------------
319//void draw_fill(coord x, coord y, color cl_fill, color cl_bound) {
320//   if (draw_get_pixel(x, y) != cl_bound && draw_get_pixel(x, y) != cl_fill) {
321//       draw_pixel(x, y, cl_fill);
322//
323//       draw_fill((x+1), y, cl_fill,cl_bound);
324//       draw_fill((x-1), y, cl_fill,cl_bound);
325//       draw_fill(x, (y+1), cl_fill,cl_bound);
326//       draw_fill(x, (y-1), cl_fill,cl_bound);
327//   }
328//}
329
330//-------------------------------------------------------------------
331void draw_circle(coord x, coord y, const unsigned int r, color cl) {
332    int dx = 0;
333    int dy = r;
334    int p=(3-(r<<1));
335
336    do {
337        draw_pixel((x+dx),(y+dy),cl);
338        draw_pixel((x+dy),(y+dx),cl);
339        draw_pixel((x+dy),(y-dx),cl);
340        draw_pixel((x+dx),(y-dy),cl);
341        draw_pixel((x-dx),(y-dy),cl);
342        draw_pixel((x-dy),(y-dx),cl);
343        draw_pixel((x-dy),(y+dx),cl);
344        draw_pixel((x-dx),(y+dy),cl);
345
346        ++dx;
347
348        if (p<0)
349            p += ((dx<<2)+6);
350        else {
351            --dy;
352            p += (((dx-dy)<<2)+10);
353        }
354    } while (dx<=dy);
355}
356
357//-------------------------------------------------------------------
358void draw_ellipse(coord xc, coord yc, unsigned int a, unsigned int b, color cl) {
359    int x = 0, y = b;
360    long a2 = (long)a*a, b2 = (long)b*b;
361    long crit1 = -((a2>>2) + (a&1) + b2);
362    long crit2 = -((b2>>2) + (b&1) + a2);
363    long crit3 = -((b2>>2) + (b&1));
364    long t = -a2*y;
365    long dxt = b2*x*2, dyt = -2*a2*y;
366    long d2xt = b2*2, d2yt = a2*2;
367
368    while (y>=0 && x<=a) {
369        draw_pixel(xc+x, yc+y, cl);
370        if (x!=0 || y!=0)
371            draw_pixel(xc-x, yc-y, cl);
372        if (x!=0 && y!=0) {
373            draw_pixel(xc+x, yc-y, cl);
374            draw_pixel(xc-x, yc+y, cl);
375        }
376        if (t + b2*x <= crit1 || t + a2*y <= crit3)
377            ++x, dxt += d2xt, t += dxt;
378        else if (t - a2*y > crit2)
379            --y, dyt += d2yt, t += dyt;
380        else {
381            ++x, dxt += d2xt, t += dxt;
382            --y, dyt += d2yt, t += dyt;
383        }
384   }
385}
386
387//-------------------------------------------------------------------
388void draw_filled_ellipse(coord xc, coord yc, unsigned int a, unsigned int b, color cl) {
389    int x = 0, y = b;
390    int rx = x, ry = y;
391    unsigned int width = 1;
392    unsigned int height = 1;
393    long a2 = (long)a*a, b2 = (long)b*b;
394    long crit1 = -((a2>>2) + (a&1) + b2);
395    long crit2 = -((b2>>2) + (b&1) + a2);
396    long crit3 = -((b2>>2) + (b&1));
397    long t = -a2*y;
398    long dxt = 2*b2*x, dyt = -2*a2*y;
399    long d2xt = 2*b2, d2yt = 2*a2;
400   
401    color cl_fill = MAKE_COLOR(BG_COLOR(cl), BG_COLOR(cl));
402
403    if (b == 0) {
404        draw_filled_rect(xc-a, yc, (a<<1)+1, 1, cl_fill);
405    } else {
406        while (y>=0 && x<=a) {
407            if (t + b2*x <= crit1 || t + a2*y <= crit3) {
408                if (height == 1)
409                    ; /* draw nothing */
410                else if (ry*2+1 > (height-1)*2) {
411                    draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+(height-1)-1, cl_fill);
412                    draw_filled_rect(xc-rx, yc+ry+1, xc-rx+width-1, yc+ry+1+(1-height)-1, cl_fill);
413                    ry -= height-1;
414                    height = 1;
415                }
416                else {
417                    draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+(ry*2+1)-1, cl_fill);
418                    ry -= ry;
419                    height = 1;
420                }
421                ++x, dxt += d2xt, t += dxt;
422                rx++;
423                width += 2;
424            }
425            else if (t - a2*y > crit2) {
426                --y, dyt += d2yt, t += dyt;
427                height++;
428            }
429            else {
430                if (ry*2+1 > height*2) {
431                    draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+height-1, cl_fill);
432                    draw_filled_rect(xc-rx, yc+ry+1, xc-rx+width-1, yc+ry+1-height-1, cl_fill);
433                }
434                else {
435                    draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+(ry*2+1)-1, cl_fill);
436                }
437                ++x, dxt += d2xt, t += dxt;
438                --y, dyt += d2yt, t += dyt;
439                rx++;
440                width += 2;
441                ry -= height;
442                height = 1;
443            }
444        }
445
446        if (ry > height) {
447            draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+height-1, cl_fill);
448            draw_filled_rect(xc-rx, yc+ry+1, xc-rx+width-1, yc+ry+1-height-1, cl_fill);
449        }
450        else {
451            draw_filled_rect(xc-rx, yc-ry, xc-rx+width-1, yc-ry+(ry*2+1)-1, cl_fill);
452        }
453    }
454}
455//-------------------------------------------------------------------
456
457// Colors for icons
458// 3 shades for each color
459//  icon_xxx[0] = dark, icon_xxx[1] = medium, icon_xxx[2] = light
460color icon_green[3], icon_red[3], icon_yellow[3], icon_grey[3];
461
462void draw_get_icon_colors()
463{
464    if((mode_get()&MODE_MASK) == MODE_REC)
465    {
466        icon_green[0]  = COLOR_ICON_REC_GREEN_DK;  icon_green[1]  = COLOR_ICON_REC_GREEN;  icon_green[2]  = COLOR_ICON_REC_GREEN_LT;
467        icon_yellow[0] = COLOR_ICON_REC_YELLOW_DK; icon_yellow[1] = COLOR_ICON_REC_YELLOW; icon_yellow[2] = COLOR_ICON_REC_YELLOW_LT;
468        icon_red[0]    = COLOR_ICON_REC_RED_DK;    icon_red[1]    = COLOR_ICON_REC_RED;    icon_red[2]    = COLOR_ICON_REC_RED_LT;
469        icon_grey[0]   = COLOR_ICON_REC_GREY_DK;   icon_grey[1]   = COLOR_ICON_REC_GREY;   icon_grey[2]   = COLOR_ICON_REC_GREY_LT;
470    }
471    else
472    {
473        icon_green[0]  = COLOR_ICON_PLY_GREEN_DK;  icon_green[1]  = COLOR_ICON_PLY_GREEN;  icon_green[2]  = COLOR_ICON_PLY_GREEN_LT;
474        icon_yellow[0] = COLOR_ICON_PLY_YELLOW_DK; icon_yellow[1] = COLOR_ICON_PLY_YELLOW; icon_yellow[2] = COLOR_ICON_PLY_YELLOW_LT;
475        icon_red[0]    = COLOR_ICON_PLY_RED_DK;    icon_red[1]    = COLOR_ICON_PLY_RED;    icon_red[2]    = COLOR_ICON_PLY_RED_LT;
476        icon_grey[0]   = COLOR_ICON_PLY_GREY_DK;   icon_grey[1]   = COLOR_ICON_PLY_GREY;   icon_grey[2]   = COLOR_ICON_PLY_GREY_LT;
477    }
478}
Note: See TracBrowser for help on using the repository browser.