svn merge -r40197:40311 ^/trunk/blender
[blender.git] / source / blender / editors / interface / interface_draw.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/interface/interface_draw.c
29  *  \ingroup edinterface
30  */
31
32
33 #include <math.h>
34 #include <string.h>
35
36 #include "DNA_color_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_screen_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_rect.h"
42 #include "BLI_utildefines.h"
43
44 #include "BKE_colortools.h"
45 #include "BKE_texture.h"
46
47
48 #include "IMB_imbuf.h"
49 #include "IMB_imbuf_types.h"
50
51 #include "BIF_gl.h"
52 #include "BIF_glutil.h"
53
54 #include "BLF_api.h"
55
56 #include "UI_interface.h"
57
58 /* own include */
59 #include "interface_intern.h"
60
61 #define UI_DISABLED_ALPHA_OFFS  -160
62
63 static int roundboxtype= UI_CNR_ALL;
64
65 void uiSetRoundBox(int type)
66 {
67         /* Not sure the roundbox function is the best place to change this
68          * if this is undone, its not that big a deal, only makes curves edges
69          * square for the  */
70         roundboxtype= type;
71         
72 }
73
74 int uiGetRoundBox(void)
75 {
76         return roundboxtype;
77 }
78
79 void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float rad)
80 {
81         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
82                                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
83         int a;
84         
85         /* mult */
86         for(a=0; a<7; a++) {
87                 vec[a][0]*= rad; vec[a][1]*= rad;
88         }
89
90         glBegin(mode);
91
92         /* start with corner right-bottom */
93         if(roundboxtype & UI_CNR_BOTTOM_RIGHT) {
94                 glVertex2f(maxx-rad, miny);
95                 for(a=0; a<7; a++) {
96                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
97                 }
98                 glVertex2f(maxx, miny+rad);
99         }
100         else glVertex2f(maxx, miny);
101         
102         /* corner right-top */
103         if(roundboxtype & UI_CNR_TOP_RIGHT) {
104                 glVertex2f(maxx, maxy-rad);
105                 for(a=0; a<7; a++) {
106                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
107                 }
108                 glVertex2f(maxx-rad, maxy);
109         }
110         else glVertex2f(maxx, maxy);
111         
112         /* corner left-top */
113         if(roundboxtype & UI_CNR_TOP_LEFT) {
114                 glVertex2f(minx+rad, maxy);
115                 for(a=0; a<7; a++) {
116                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
117                 }
118                 glVertex2f(minx, maxy-rad);
119         }
120         else glVertex2f(minx, maxy);
121         
122         /* corner left-bottom */
123         if(roundboxtype & UI_CNR_BOTTOM_LEFT) {
124                 glVertex2f(minx, miny+rad);
125                 for(a=0; a<7; a++) {
126                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
127                 }
128                 glVertex2f(minx+rad, miny);
129         }
130         else glVertex2f(minx, miny);
131         
132         glEnd();
133 }
134
135 static void round_box_shade_col(const float col1[3], float const col2[3], const float fac)
136 {
137         float col[3];
138
139         col[0]= (fac*col1[0] + (1.0f-fac)*col2[0]);
140         col[1]= (fac*col1[1] + (1.0f-fac)*col2[1]);
141         col[2]= (fac*col1[2] + (1.0f-fac)*col2[2]);
142         glColor3fv(col);
143 }
144
145 /* linear horizontal shade within button or in outline */
146 /* view2d scrollers use it */
147 void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
148 {
149         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
150                                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
151         const float div= maxy - miny;
152         const float idiv= 1.0f / div;
153         float coltop[3], coldown[3], color[4];
154         int a;
155         
156         /* mult */
157         for(a=0; a<7; a++) {
158                 vec[a][0]*= rad; vec[a][1]*= rad;
159         }
160         /* get current color, needs to be outside of glBegin/End */
161         glGetFloatv(GL_CURRENT_COLOR, color);
162
163         /* 'shade' defines strength of shading */       
164         coltop[0]= color[0]+shadetop; if(coltop[0]>1.0f) coltop[0]= 1.0f;
165         coltop[1]= color[1]+shadetop; if(coltop[1]>1.0f) coltop[1]= 1.0f;
166         coltop[2]= color[2]+shadetop; if(coltop[2]>1.0f) coltop[2]= 1.0f;
167         coldown[0]= color[0]+shadedown; if(coldown[0]<0.0f) coldown[0]= 0.0f;
168         coldown[1]= color[1]+shadedown; if(coldown[1]<0.0f) coldown[1]= 0.0f;
169         coldown[2]= color[2]+shadedown; if(coldown[2]<0.0f) coldown[2]= 0.0f;
170
171         glShadeModel(GL_SMOOTH);
172         glBegin(mode);
173
174         /* start with corner right-bottom */
175         if(roundboxtype & UI_CNR_BOTTOM_RIGHT) {
176                 
177                 round_box_shade_col(coltop, coldown, 0.0);
178                 glVertex2f(maxx-rad, miny);
179                 
180                 for(a=0; a<7; a++) {
181                         round_box_shade_col(coltop, coldown, vec[a][1]*idiv);
182                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
183                 }
184                 
185                 round_box_shade_col(coltop, coldown, rad*idiv);
186                 glVertex2f(maxx, miny+rad);
187         }
188         else {
189                 round_box_shade_col(coltop, coldown, 0.0);
190                 glVertex2f(maxx, miny);
191         }
192         
193         /* corner right-top */
194         if(roundboxtype & UI_CNR_TOP_RIGHT) {
195                 
196                 round_box_shade_col(coltop, coldown, (div-rad)*idiv);
197                 glVertex2f(maxx, maxy-rad);
198                 
199                 for(a=0; a<7; a++) {
200                         round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])*idiv);
201                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
202                 }
203                 round_box_shade_col(coltop, coldown, 1.0);
204                 glVertex2f(maxx-rad, maxy);
205         }
206         else {
207                 round_box_shade_col(coltop, coldown, 1.0);
208                 glVertex2f(maxx, maxy);
209         }
210         
211         /* corner left-top */
212         if(roundboxtype & UI_CNR_TOP_LEFT) {
213                 
214                 round_box_shade_col(coltop, coldown, 1.0);
215                 glVertex2f(minx+rad, maxy);
216                 
217                 for(a=0; a<7; a++) {
218                         round_box_shade_col(coltop, coldown, (div-vec[a][1])*idiv);
219                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
220                 }
221                 
222                 round_box_shade_col(coltop, coldown, (div-rad)*idiv);
223                 glVertex2f(minx, maxy-rad);
224         }
225         else {
226                 round_box_shade_col(coltop, coldown, 1.0);
227                 glVertex2f(minx, maxy);
228         }
229         
230         /* corner left-bottom */
231         if(roundboxtype & UI_CNR_BOTTOM_LEFT) {
232                 
233                 round_box_shade_col(coltop, coldown, rad*idiv);
234                 glVertex2f(minx, miny+rad);
235                 
236                 for(a=0; a<7; a++) {
237                         round_box_shade_col(coltop, coldown, (rad-vec[a][1])*idiv);
238                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
239                 }
240                 
241                 round_box_shade_col(coltop, coldown, 0.0);
242                 glVertex2f(minx+rad, miny);
243         }
244         else {
245                 round_box_shade_col(coltop, coldown, 0.0);
246                 glVertex2f(minx, miny);
247         }
248         
249         glEnd();
250         glShadeModel(GL_FLAT);
251 }
252
253 /* linear vertical shade within button or in outline */
254 /* view2d scrollers use it */
255 void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight)
256 {
257         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
258                                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
259         const float div= maxx - minx;
260         const float idiv= 1.0f / div;
261         float colLeft[3], colRight[3], color[4];
262         int a;
263         
264         /* mult */
265         for(a=0; a<7; a++) {
266                 vec[a][0]*= rad; vec[a][1]*= rad;
267         }
268         /* get current color, needs to be outside of glBegin/End */
269         glGetFloatv(GL_CURRENT_COLOR, color);
270
271         /* 'shade' defines strength of shading */       
272         colLeft[0]= color[0]+shadeLeft; if(colLeft[0]>1.0f) colLeft[0]= 1.0f;
273         colLeft[1]= color[1]+shadeLeft; if(colLeft[1]>1.0f) colLeft[1]= 1.0f;
274         colLeft[2]= color[2]+shadeLeft; if(colLeft[2]>1.0f) colLeft[2]= 1.0f;
275         colRight[0]= color[0]+shadeRight; if(colRight[0]<0.0f) colRight[0]= 0.0f;
276         colRight[1]= color[1]+shadeRight; if(colRight[1]<0.0f) colRight[1]= 0.0f;
277         colRight[2]= color[2]+shadeRight; if(colRight[2]<0.0f) colRight[2]= 0.0f;
278
279         glShadeModel(GL_SMOOTH);
280         glBegin(mode);
281
282         /* start with corner right-bottom */
283         if(roundboxtype & UI_CNR_BOTTOM_RIGHT) {
284                 round_box_shade_col(colLeft, colRight, 0.0);
285                 glVertex2f(maxx-rad, miny);
286                 
287                 for(a=0; a<7; a++) {
288                         round_box_shade_col(colLeft, colRight, vec[a][0]*idiv);
289                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
290                 }
291                 
292                 round_box_shade_col(colLeft, colRight, rad*idiv);
293                 glVertex2f(maxx, miny+rad);
294         }
295         else {
296                 round_box_shade_col(colLeft, colRight, 0.0);
297                 glVertex2f(maxx, miny);
298         }
299         
300         /* corner right-top */
301         if(roundboxtype & UI_CNR_TOP_RIGHT) {
302                 round_box_shade_col(colLeft, colRight, 0.0);
303                 glVertex2f(maxx, maxy-rad);
304                 
305                 for(a=0; a<7; a++) {
306                         
307                         round_box_shade_col(colLeft, colRight, (div-rad-vec[a][0])*idiv);
308                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
309                 }
310                 round_box_shade_col(colLeft, colRight, (div-rad)*idiv);
311                 glVertex2f(maxx-rad, maxy);
312         }
313         else {
314                 round_box_shade_col(colLeft, colRight, 0.0);
315                 glVertex2f(maxx, maxy);
316         }
317         
318         /* corner left-top */
319         if(roundboxtype & UI_CNR_TOP_LEFT) {
320                 round_box_shade_col(colLeft, colRight, (div-rad)*idiv);
321                 glVertex2f(minx+rad, maxy);
322                 
323                 for(a=0; a<7; a++) {
324                         round_box_shade_col(colLeft, colRight, (div-rad+vec[a][0])*idiv);
325                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
326                 }
327                 
328                 round_box_shade_col(colLeft, colRight, 1.0);
329                 glVertex2f(minx, maxy-rad);
330         }
331         else {
332                 round_box_shade_col(colLeft, colRight, 1.0);
333                 glVertex2f(minx, maxy);
334         }
335         
336         /* corner left-bottom */
337         if(roundboxtype & UI_CNR_BOTTOM_LEFT) {
338                 round_box_shade_col(colLeft, colRight, 1.0);
339                 glVertex2f(minx, miny+rad);
340                 
341                 for(a=0; a<7; a++) {
342                         round_box_shade_col(colLeft, colRight, (vec[a][0])*idiv);
343                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
344                 }
345                 
346                 round_box_shade_col(colLeft, colRight, 1.0);
347                 glVertex2f(minx+rad, miny);
348         }
349         else {
350                 round_box_shade_col(colLeft, colRight, 1.0);
351                 glVertex2f(minx, miny);
352         }
353         
354         glEnd();
355         glShadeModel(GL_FLAT);
356 }
357
358 /* plain antialiased unfilled rectangle */
359 void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
360 {
361         float color[4];
362         
363         if(roundboxtype & UI_RB_ALPHA) {
364                 glGetFloatv(GL_CURRENT_COLOR, color);
365                 color[3]= 0.5;
366                 glColor4fv(color);
367                 glEnable( GL_BLEND );
368         }
369         
370         /* set antialias line */
371         glEnable( GL_LINE_SMOOTH );
372         glEnable( GL_BLEND );
373
374         uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
375    
376         glDisable( GL_BLEND );
377         glDisable( GL_LINE_SMOOTH );
378 }
379
380 /* plain fake antialiased unfilled round rectangle */
381 #if 0 /* UNUSED 2.5 */
382 static void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
383 {
384         float color[4], alpha;
385         float raddiff;
386         int i, passes=4;
387         
388         /* get the color and divide up the alpha */
389         glGetFloatv(GL_CURRENT_COLOR, color);
390         alpha = 1; //color[3];
391         color[3]= 0.5*alpha/(float)passes;
392         glColor4fv(color);
393         
394         /* set the 'jitter amount' */
395         raddiff = (1/(float)passes) * asp;
396         
397         glEnable( GL_BLEND );
398         
399         /* draw lots of lines on top of each other */
400         for (i=passes; i>=(-passes); i--) {
401                 uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad+(i*raddiff));
402         }
403         
404         glDisable( GL_BLEND );
405         
406         color[3] = alpha;
407         glColor4fv(color);
408 }
409 #endif
410
411 /* (old, used in outliner) plain antialiased filled box */
412 void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
413 {
414         float color[4];
415         
416         if(roundboxtype & UI_RB_ALPHA) {
417                 glGetFloatv(GL_CURRENT_COLOR, color);
418                 color[3]= 0.5;
419                 glColor4fv(color);
420                 glEnable( GL_BLEND );
421         }
422         
423         /* solid part */
424         uiDrawBox(GL_POLYGON, minx, miny, maxx, maxy, rad);
425         
426         /* set antialias line */
427         glEnable( GL_LINE_SMOOTH );
428         glEnable( GL_BLEND );
429         
430         uiDrawBox(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
431         
432         glDisable( GL_BLEND );
433         glDisable( GL_LINE_SMOOTH );
434 }
435
436
437 /* ************** generic embossed rect, for window sliders etc ************* */
438
439
440 /* text_draw.c uses this */
441 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
442 {
443         
444         /* below */
445         if(sel) glColor3ub(200,200,200);
446         else glColor3ub(50,50,50);
447         fdrawline(x1, y1, x2, y1);
448
449         /* right */
450         fdrawline(x2, y1, x2, y2);
451         
452         /* top */
453         if(sel) glColor3ub(50,50,50);
454         else glColor3ub(200,200,200);
455         fdrawline(x1, y2, x2, y2);
456
457         /* left */
458         fdrawline(x1, y1, x1, y2);
459         
460 }
461
462 /* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
463
464 void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
465 {
466 #ifdef WITH_HEADLESS
467         (void)rect;
468 #else
469         ImBuf *ibuf= (ImBuf *)but->poin;
470         //GLint scissor[4];
471         //int w, h;
472
473         if (!ibuf) return;
474         
475         /* scissor doesn't seem to be doing the right thing...?
476         //glColor4f(1.0, 0.f, 0.f, 1.f);
477         //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
478
479         w = (rect->xmax - rect->xmin);
480         h = (rect->ymax - rect->ymin);
481         // prevent drawing outside widget area
482         glGetIntegerv(GL_SCISSOR_BOX, scissor);
483         glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
484         */
485         
486         glEnable(GL_BLEND);
487         glColor4f(0.0, 0.0, 0.0, 0.0);
488         
489         glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
490         //glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
491         
492         glDisable(GL_BLEND);
493         
494         /* 
495         // restore scissortest
496         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
497         */
498         
499 #endif
500 }
501
502 #if 0
503 #ifdef INTERNATIONAL
504 static void ui_draw_but_CHARTAB(uiBut *but)
505 {
506         /* XXX 2.50 bad global access */
507         /* Some local variables */
508         float sx, sy, ex, ey;
509         float width, height;
510         float butw, buth;
511         int x, y, cs;
512         wchar_t wstr[2];
513         unsigned char ustr[16];
514         PackedFile *pf;
515         int result = 0;
516         int charmax = G.charmax;
517         
518         /* FO_BUILTIN_NAME font in use. There are TTF FO_BUILTIN_NAME and non-TTF FO_BUILTIN_NAME fonts */
519         if(!strcmp(G.selfont->name, FO_BUILTIN_NAME)) {
520                 if(G.ui_international == TRUE) {
521                         charmax = 0xff;
522                 }
523                 else {
524                         charmax = 0xff;
525                 }
526         }
527
528         /* Category list exited without selecting the area */
529         if(G.charmax == 0)
530                 charmax = G.charmax = 0xffff;
531
532         /* Calculate the size of the button */
533         width = abs(rect->xmax - rect->xmin);
534         height = abs(rect->ymax - rect->ymin);
535         
536         butw = floor(width / 12);
537         buth = floor(height / 6);
538         
539         /* Initialize variables */
540         sx = rect->xmin;
541         ex = rect->xmin + butw;
542         sy = rect->ymin + height - buth;
543         ey = rect->ymin + height;
544
545         cs = G.charstart;
546
547         /* Set the font, in case it is not FO_BUILTIN_NAME font */
548         if(G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) {
549                 // Is the font file packed, if so then use the packed file
550                 if(G.selfont->packedfile) {
551                         pf = G.selfont->packedfile;             
552                         FTF_SetFont(pf->data, pf->size, 14.0);
553                 }
554                 else {
555                         char tmpStr[256];
556                         int err;
557
558                         BLI_strncpy(tmpStr, G.selfont->name, sizeof(tmpStr));
559                         BLI_path_abs(tmpStr, G.main->name);
560                         err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
561                 }
562         }
563         else {
564                 if(G.ui_international == TRUE) {
565                         FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0);
566                 }
567         }
568
569         /* Start drawing the button itself */
570         glShadeModel(GL_SMOOTH);
571
572         glColor3ub(200,  200,  200);
573         glRectf((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
574
575         glColor3ub(0,  0,  0);
576         for(y = 0; y < 6; y++) {
577                 // Do not draw more than the category allows
578                 if(cs > charmax) break;
579
580                 for(x = 0; x < 12; x++)
581                 {
582                         // Do not draw more than the category allows
583                         if(cs > charmax) break;
584
585                         // Draw one grid cell
586                         glBegin(GL_LINE_LOOP);
587                                 glVertex2f(sx, sy);
588                                 glVertex2f(ex, sy);
589                                 glVertex2f(ex, ey);
590                                 glVertex2f(sx, ey);                             
591                         glEnd();        
592
593                         // Draw character inside the cell
594                         memset(wstr, 0, sizeof(wchar_t)*2);
595                         memset(ustr, 0, 16);
596
597                         // Set the font to be either unicode or FO_BUILTIN_NAME 
598                         wstr[0] = cs;
599                         if(strcmp(G.selfont->name, FO_BUILTIN_NAME))
600                         {
601                                 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
602                         }
603                         else
604                         {
605                                 if(G.ui_international == TRUE)
606                                 {
607                                         wcs2utf8s((char *)ustr, (wchar_t *)wstr);
608                                 }
609                                 else
610                                 {
611                                         ustr[0] = cs;
612                                         ustr[1] = 0;
613                                 }
614                         }
615
616                         if((G.selfont && strcmp(G.selfont->name, FO_BUILTIN_NAME)) || (G.selfont && !strcmp(G.selfont->name, FO_BUILTIN_NAME) && G.ui_international == TRUE))
617                         {
618                                 float wid;
619                                 float llx, lly, llz, urx, ury, urz;
620                                 float dx, dy;
621                                 float px, py;
622         
623                                 // Calculate the position
624                                 wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
625                                 FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
626                                 dx = urx-llx;
627                                 dy = ury-lly;
628
629                                 // This isn't fully functional since the but->aspect isn't working like I suspected
630                                 px = sx + ((butw/but->aspect)-dx)/2;
631                                 py = sy + ((buth/but->aspect)-dy)/2;
632
633                                 // Set the position and draw the character
634                                 ui_rasterpos_safe(px, py, but->aspect);
635                                 FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
636                         }
637                         else
638                         {
639                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
640                                 UI_DrawString(but->font, (char *) ustr, 0);
641                         }
642         
643                         // Calculate the next position and character
644                         sx += butw; ex +=butw;
645                         cs++;
646                 }
647                 /* Add the y position and reset x position */
648                 sy -= buth; 
649                 ey -= buth;
650                 sx = rect->xmin;
651                 ex = rect->xmin + butw;
652         }       
653         glShadeModel(GL_FLAT);
654
655         /* Return Font Settings to original */
656         if(U.fontsize && U.fontname[0]) {
657                 result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize);
658         }
659         else if (U.fontsize) {
660                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
661         }
662
663         if (result == 0) {
664                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
665         }
666         
667         /* resets the font size */
668         if(G.ui_international == TRUE) {
669                 // uiSetCurFont(but->block, UI_HELV);
670         }
671 }
672
673 #endif // INTERNATIONAL
674 #endif
675
676 static void draw_scope_end(rctf *rect, GLint *scissor)
677 {
678         float scaler_x1, scaler_x2;
679         
680         /* restore scissortest */
681         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
682         
683         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
684         
685         /* scale widget */
686         scaler_x1 = rect->xmin + (rect->xmax - rect->xmin)/2 - SCOPE_RESIZE_PAD;
687         scaler_x2 = rect->xmin + (rect->xmax - rect->xmin)/2 + SCOPE_RESIZE_PAD;
688         
689         glColor4f(0.f, 0.f, 0.f, 0.25f);
690         fdrawline(scaler_x1, rect->ymin-4, scaler_x2, rect->ymin-4);
691         fdrawline(scaler_x1, rect->ymin-7, scaler_x2, rect->ymin-7);
692         glColor4f(1.f, 1.f, 1.f, 0.25f);
693         fdrawline(scaler_x1, rect->ymin-5, scaler_x2, rect->ymin-5);
694         fdrawline(scaler_x1, rect->ymin-8, scaler_x2, rect->ymin-8);
695         
696         /* outline */
697         glColor4f(0.f, 0.f, 0.f, 0.5f);
698         uiSetRoundBox(UI_CNR_ALL);
699         uiDrawBox(GL_LINE_LOOP, rect->xmin-1, rect->ymin, rect->xmax+1, rect->ymax+1, 3.0f);
700 }
701
702 static void histogram_draw_one(float r, float g, float b, float alpha, float x, float y, float w, float h, float *data, int res)
703 {
704         int i;
705         
706         /* under the curve */
707         glBlendFunc(GL_SRC_ALPHA, GL_ONE);
708         glColor4f(r, g, b, alpha);
709         
710         glShadeModel(GL_FLAT);
711         glBegin(GL_QUAD_STRIP);
712         glVertex2f(x, y);
713         glVertex2f(x, y + (data[0]*h));
714         for (i=1; i < res; i++) {
715                 float x2 = x + i * (w/(float)res);
716                 glVertex2f(x2, y + (data[i]*h));
717                 glVertex2f(x2, y);
718         }
719         glEnd();
720         
721         /* curve outline */
722         glColor4f(0.f, 0.f, 0.f, 0.25f);
723         
724         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
725         glEnable(GL_LINE_SMOOTH);
726         glBegin(GL_LINE_STRIP);
727         for (i=0; i < res; i++) {
728                 float x2 = x + i * (w/(float)res);
729                 glVertex2f(x2, y + (data[i]*h));
730         }
731         glEnd();
732         glDisable(GL_LINE_SMOOTH);
733 }
734
735 void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
736 {
737         Histogram *hist = (Histogram *)but->poin;
738         int res = hist->x_resolution;
739         rctf rect;
740         int i;
741         float w, h;
742         //float alpha;
743         GLint scissor[4];
744         
745         rect.xmin = (float)recti->xmin+1;
746         rect.xmax = (float)recti->xmax-1;
747         rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
748         rect.ymax = (float)recti->ymax-1;
749         
750         w = rect.xmax - rect.xmin;
751         h = (rect.ymax - rect.ymin) * hist->ymax;
752         
753         glEnable(GL_BLEND);
754         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
755         
756         glColor4f(0.f, 0.f, 0.f, 0.3f);
757         uiSetRoundBox(UI_CNR_ALL);
758         uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
759
760         /* need scissor test, histogram can draw outside of boundary */
761         glGetIntegerv(GL_VIEWPORT, scissor);
762         glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
763
764         glColor4f(1.f, 1.f, 1.f, 0.08f);
765         /* draw grid lines here */
766         for (i=1; i<4; i++) {
767                 fdrawline(rect.xmin, rect.ymin+(i/4.f)*h, rect.xmax, rect.ymin+(i/4.f)*h);
768                 fdrawline(rect.xmin+(i/4.f)*w, rect.ymin, rect.xmin+(i/4.f)*w, rect.ymax);
769         }
770         
771         if (hist->mode == HISTO_MODE_LUMA)
772                 histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res);
773         else {
774                 if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R)
775                         histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res);
776                 if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G)
777                         histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res);
778                 if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B)
779                         histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res);
780         }
781         
782         /* outline, scale gripper */
783         draw_scope_end(&rect, scissor);
784 }
785
786 void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
787 {
788         Scopes *scopes = (Scopes *)but->poin;
789         rctf rect;
790         int i, c;
791         float w, w3, h, alpha, yofs;
792         GLint scissor[4];
793         float colors[3][3]= MAT3_UNITY;
794         float colorsycc[3][3] = {{1,0,1},{1,1,0},{0,1,1}};
795         float colors_alpha[3][3], colorsycc_alpha[3][3]; /* colors  pre multiplied by alpha for speed up */
796         float min, max;
797         
798         if (scopes==NULL) return;
799         
800         rect.xmin = (float)recti->xmin+1;
801         rect.xmax = (float)recti->xmax-1;
802         rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
803         rect.ymax = (float)recti->ymax-1;
804         
805         if (scopes->wavefrm_yfac < 0.5f )
806                 scopes->wavefrm_yfac =0.98f;
807         w = rect.xmax - rect.xmin-7;
808         h = (rect.ymax - rect.ymin)*scopes->wavefrm_yfac;
809         yofs= rect.ymin + (rect.ymax - rect.ymin -h)/2.0f;
810         w3=w/3.0f;
811         
812         /* log scale for alpha */
813         alpha = scopes->wavefrm_alpha*scopes->wavefrm_alpha;
814         
815         for(c=0; c<3; c++) {
816                 for(i=0; i<3; i++) {
817                         colors_alpha[c][i] = colors[c][i] * alpha;
818                         colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
819                 }
820         }
821                         
822         glEnable(GL_BLEND);
823         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
824         
825         glColor4f(0.f, 0.f, 0.f, 0.3f);
826         uiSetRoundBox(UI_CNR_ALL);
827         uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
828         
829
830         /* need scissor test, waveform can draw outside of boundary */
831         glGetIntegerv(GL_VIEWPORT, scissor);
832         glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
833
834         glColor4f(1.f, 1.f, 1.f, 0.08f);
835         /* draw grid lines here */
836         for (i=0; i<6; i++) {
837                 char str[4];
838                 sprintf(str,"%-3d",i*20);
839                 str[3]='\0';
840                 fdrawline(rect.xmin+22, yofs+(i/5.f)*h, rect.xmax+1, yofs+(i/5.f)*h);
841                 BLF_draw_default(rect.xmin+1, yofs-5+(i/5.f)*h, 0, str, sizeof(str)-1);
842                 /* in the loop because blf_draw reset it */
843                 glEnable(GL_BLEND);
844                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
845         }
846         /* 3 vertical separation */
847         if (scopes->wavefrm_mode!= SCOPES_WAVEFRM_LUMA) {
848                 for (i=1; i<3; i++) {
849                         fdrawline(rect.xmin+i*w3, rect.ymin, rect.xmin+i*w3, rect.ymax);
850                 }
851         }
852         
853         /* separate min max zone on the right */
854         fdrawline(rect.xmin+w, rect.ymin, rect.xmin+w, rect.ymax);
855         /* 16-235-240 level in case of ITU-R BT601/709 */
856         glColor4f(1.f, 0.4f, 0.f, 0.2f);
857         if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)){
858                 fdrawline(rect.xmin+22, yofs+h*16.0f/255.0f, rect.xmax+1, yofs+h*16.0f/255.0f);
859                 fdrawline(rect.xmin+22, yofs+h*235.0f/255.0f, rect.xmin+w3, yofs+h*235.0f/255.0f);
860                 fdrawline(rect.xmin+3*w3, yofs+h*235.0f/255.0f, rect.xmax+1, yofs+h*235.0f/255.0f);
861                 fdrawline(rect.xmin+w3, yofs+h*240.0f/255.0f, rect.xmax+1, yofs+h*240.0f/255.0f);
862         }
863         /* 7.5 IRE black point level for NTSC */
864         if (scopes->wavefrm_mode== SCOPES_WAVEFRM_LUMA)
865                 fdrawline(rect.xmin, yofs+h*0.075f, rect.xmax+1, yofs+h*0.075f);
866
867         if (scopes->ok && scopes->waveform_1 != NULL) {
868                 
869                 /* LUMA (1 channel) */
870                 glBlendFunc(GL_ONE,GL_ONE);
871                 glColor3f(alpha, alpha, alpha);
872                 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA){
873
874                         glBlendFunc(GL_ONE,GL_ONE);
875                         
876                         glPushMatrix();
877                         glEnableClientState(GL_VERTEX_ARRAY);
878                         
879                         glTranslatef(rect.xmin, yofs, 0.f);
880                         glScalef(w, h, 0.f);
881                         glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
882                         glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
883                                         
884                         glDisableClientState(GL_VERTEX_ARRAY);
885                         glPopMatrix();
886
887                         /* min max */
888                         glColor3f(.5f, .5f, .5f);
889                         min= yofs+scopes->minmax[0][0]*h;
890                         max= yofs+scopes->minmax[0][1]*h;
891                         CLAMP(min, rect.ymin, rect.ymax);
892                         CLAMP(max, rect.ymin, rect.ymax);
893                         fdrawline(rect.xmax-3,min,rect.xmax-3,max);
894                 }
895
896                 /* RGB / YCC (3 channels) */
897                 else if (ELEM4(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709, SCOPES_WAVEFRM_YCC_JPEG)) {
898                         int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB);
899                         
900                         glBlendFunc(GL_ONE,GL_ONE);
901                         
902                         glPushMatrix();
903                         glEnableClientState(GL_VERTEX_ARRAY);
904                         
905                         glTranslatef(rect.xmin, yofs, 0.f);
906                         glScalef(w3, h, 0.f);
907                         
908                         glColor3fv((rgb)?colors_alpha[0]:colorsycc_alpha[0]);
909                         glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
910                         glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
911
912                         glTranslatef(1.f, 0.f, 0.f);
913                         glColor3fv((rgb)?colors_alpha[1]:colorsycc_alpha[1]);
914                         glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2);
915                         glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
916                         
917                         glTranslatef(1.f, 0.f, 0.f);
918                         glColor3fv((rgb)?colors_alpha[2]:colorsycc_alpha[2]);
919                         glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3);
920                         glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
921                         
922                         glDisableClientState(GL_VERTEX_ARRAY);
923                         glPopMatrix();
924
925                         
926                         /* min max */
927                         for (c=0; c<3; c++) {
928                                 if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB)
929                                         glColor3f(colors[c][0]*0.75f, colors[c][1]*0.75f, colors[c][2]*0.75f);
930                                 else
931                                         glColor3f(colorsycc[c][0]*0.75f, colorsycc[c][1]*0.75f, colorsycc[c][2]*0.75f);
932                                 min= yofs+scopes->minmax[c][0]*h;
933                                 max= yofs+scopes->minmax[c][1]*h;
934                                 CLAMP(min, rect.ymin, rect.ymax);
935                                 CLAMP(max, rect.ymin, rect.ymax);
936                                 fdrawline(rect.xmin+w+2+c*2,min,rect.xmin+w+2+c*2,max);
937                         }
938                 }
939                 
940         }
941         
942         /* outline, scale gripper */
943         draw_scope_end(&rect, scissor);
944 }
945
946 static float polar_to_x(float center, float diam, float ampli, float angle)
947 {
948         return center + diam * ampli * cosf(angle);
949 }
950
951 static float polar_to_y(float center, float diam, float ampli, float angle)
952 {
953         return center + diam * ampli * sinf(angle);
954 }
955
956 static void vectorscope_draw_target(float centerx, float centery, float diam, const float colf[3])
957 {
958         float y,u,v;
959         float tangle=0.f, tampli;
960         float dangle, dampli, dangle2, dampli2;
961
962         rgb_to_yuv(colf[0], colf[1], colf[2], &y, &u, &v);
963         if (u>0 && v>=0) tangle=atanf(v/u);
964         else if (u>0 && v<0) tangle= atanf(v/u) + 2.0f * (float)M_PI;
965         else if (u<0) tangle=atanf(v/u) + (float)M_PI;
966         else if (u==0 && v > 0.0f) tangle= (float)M_PI/2.0f;
967         else if (u==0 && v < 0.0f) tangle=-(float)M_PI/2.0f;
968         tampli= sqrtf(u*u+v*v);
969
970         /* small target vary by 2.5 degree and 2.5 IRE unit */
971         glColor4f(1.0f, 1.0f, 1.0, 0.12f);
972         dangle= DEG2RADF(2.5f);
973         dampli= 2.5f/200.0f;
974         glBegin(GL_LINE_STRIP);
975         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
976         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle), polar_to_y(centery,diam,tampli-dampli,tangle+dangle));
977         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle), polar_to_y(centery,diam,tampli-dampli,tangle-dangle));
978         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle), polar_to_y(centery,diam,tampli+dampli,tangle-dangle));
979         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
980         glEnd();
981         /* big target vary by 10 degree and 20% amplitude */
982         glColor4f(1.0f, 1.0f, 1.0, 0.12f);
983         dangle= DEG2RADF(10.0f);
984         dampli= 0.2f*tampli;
985         dangle2= DEG2RADF(5.0f);
986         dampli2= 0.5f*dampli;
987         glBegin(GL_LINE_STRIP);
988         glVertex2f(polar_to_x(centerx,diam,tampli+dampli-dampli2,tangle+dangle), polar_to_y(centery,diam,tampli+dampli-dampli2,tangle+dangle));
989         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle), polar_to_y(centery,diam,tampli+dampli,tangle+dangle));
990         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle+dangle-dangle2), polar_to_y(centery,diam,tampli+dampli,tangle+dangle-dangle2));
991         glEnd();
992         glBegin(GL_LINE_STRIP);
993         glVertex2f(polar_to_x(centerx,diam,tampli-dampli+dampli2,tangle+dangle), polar_to_y(centery ,diam,tampli-dampli+dampli2,tangle+dangle));
994         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle), polar_to_y(centery,diam,tampli-dampli,tangle+dangle));
995         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle+dangle-dangle2), polar_to_y(centery,diam,tampli-dampli,tangle+dangle-dangle2));
996         glEnd();
997         glBegin(GL_LINE_STRIP);
998         glVertex2f(polar_to_x(centerx,diam,tampli-dampli+dampli2,tangle-dangle), polar_to_y(centery,diam,tampli-dampli+dampli2,tangle-dangle));
999         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle), polar_to_y(centery,diam,tampli-dampli,tangle-dangle));
1000         glVertex2f(polar_to_x(centerx,diam,tampli-dampli,tangle-dangle+dangle2), polar_to_y(centery,diam,tampli-dampli,tangle-dangle+dangle2));
1001         glEnd();
1002         glBegin(GL_LINE_STRIP);
1003         glVertex2f(polar_to_x(centerx,diam,tampli+dampli-dampli2,tangle-dangle), polar_to_y(centery,diam,tampli+dampli-dampli2,tangle-dangle));
1004         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle), polar_to_y(centery,diam,tampli+dampli,tangle-dangle));
1005         glVertex2f(polar_to_x(centerx,diam,tampli+dampli,tangle-dangle+dangle2), polar_to_y(centery,diam,tampli+dampli,tangle-dangle+dangle2));
1006         glEnd();
1007 }
1008
1009 void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
1010 {
1011         const float skin_rad= DEG2RADF(123.0f); /* angle in radians of the skin tone line */
1012         Scopes *scopes = (Scopes *)but->poin;
1013         rctf rect;
1014         int i, j;
1015         float w, h, centerx, centery, diam;
1016         float alpha;
1017         const float colors[6][3]={{.75,0,0},{.75,.75,0},{0,.75,0},{0,.75,.75},{0,0,.75},{.75,0,.75}};
1018         GLint scissor[4];
1019         
1020         rect.xmin = (float)recti->xmin+1;
1021         rect.xmax = (float)recti->xmax-1;
1022         rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2;
1023         rect.ymax = (float)recti->ymax-1;
1024         
1025         w = rect.xmax - rect.xmin;
1026         h = rect.ymax - rect.ymin;
1027         centerx = rect.xmin + w/2;
1028         centery = rect.ymin + h/2;
1029         diam= (w<h)?w:h;
1030         
1031         alpha = scopes->vecscope_alpha*scopes->vecscope_alpha*scopes->vecscope_alpha;
1032                         
1033         glEnable(GL_BLEND);
1034         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1035         
1036         glColor4f(0.f, 0.f, 0.f, 0.3f);
1037         uiSetRoundBox(UI_CNR_ALL);
1038         uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f);
1039
1040         /* need scissor test, hvectorscope can draw outside of boundary */
1041         glGetIntegerv(GL_VIEWPORT, scissor);
1042         glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1));
1043         
1044         glColor4f(1.f, 1.f, 1.f, 0.08f);
1045         /* draw grid elements */
1046         /* cross */
1047         fdrawline(centerx - (diam/2)-5, centery, centerx + (diam/2)+5, centery);
1048         fdrawline(centerx, centery - (diam/2)-5, centerx, centery + (diam/2)+5);
1049         /* circles */
1050         for(j=0; j<5; j++) {
1051                 glBegin(GL_LINE_STRIP);
1052                 for(i=0; i<=360; i=i+15) {
1053                         const float a= DEG2RADF((float)i);
1054                         const float r= (j+1)/10.0f;
1055                         glVertex2f(polar_to_x(centerx,diam,r,a), polar_to_y(centery,diam,r,a));
1056                 }
1057                 glEnd();
1058         }
1059         /* skin tone line */
1060         glColor4f(1.f, 0.4f, 0.f, 0.2f);
1061         fdrawline(polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery,diam,0.5,skin_rad),
1062                   polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery,diam,0.1,skin_rad));
1063         /* saturation points */
1064         for(i=0; i<6; i++)
1065                 vectorscope_draw_target(centerx, centery, diam, colors[i]);
1066         
1067         if (scopes->ok && scopes->vecscope != NULL) {
1068                 /* pixel point cloud */
1069                 glBlendFunc(GL_ONE,GL_ONE);
1070                 glColor3f(alpha, alpha, alpha);
1071
1072                 glPushMatrix();
1073                 glEnableClientState(GL_VERTEX_ARRAY);
1074
1075                 glTranslatef(centerx, centery, 0.f);
1076                 glScalef(diam, diam, 0.f);
1077
1078                 glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
1079                 glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
1080                 
1081                 glDisableClientState(GL_VERTEX_ARRAY);
1082                 glPopMatrix();
1083         }
1084
1085         /* outline, scale gripper */
1086         draw_scope_end(&rect, scissor);
1087                 
1088         glDisable(GL_BLEND);
1089 }
1090
1091 void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
1092 {
1093         ColorBand *coba;
1094         CBData *cbd;
1095         float x1, y1, sizex, sizey;
1096         float v3[2], v1[2], v2[2], v1a[2], v2a[2];
1097         int a;
1098         float pos, colf[4]= {0,0,0,0}; /* initialize incase the colorband isnt valid */
1099                 
1100         coba= (ColorBand *)(but->editcoba? but->editcoba: but->poin);
1101         if(coba==NULL) return;
1102         
1103         x1= rect->xmin;
1104         y1= rect->ymin;
1105         sizex= rect->xmax-x1;
1106         sizey= rect->ymax-y1;
1107
1108         /* first background, to show tranparency */
1109
1110         glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
1111         glRectf(x1, y1, x1+sizex, y1+sizey);
1112         glEnable(GL_POLYGON_STIPPLE);
1113         glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
1114         glPolygonStipple(checker_stipple_sml);
1115         glRectf(x1, y1, x1+sizex, y1+sizey);
1116         glDisable(GL_POLYGON_STIPPLE);
1117
1118         glShadeModel(GL_FLAT);
1119         glEnable(GL_BLEND);
1120         
1121         cbd= coba->data;
1122         
1123         v1[0]= v2[0]= x1;
1124         v1[1]= y1;
1125         v2[1]= y1+sizey;
1126         
1127         glBegin(GL_QUAD_STRIP);
1128         
1129         glColor4fv( &cbd->r );
1130         glVertex2fv(v1); glVertex2fv(v2);
1131         
1132         for( a = 1; a <= sizex; a++ ) {
1133                 pos = ((float)a) / (sizex-1);
1134                 do_colorband( coba, pos, colf );
1135                 if (but->block->color_profile != BLI_PR_NONE)
1136                         linearrgb_to_srgb_v3_v3(colf, colf);
1137                 
1138                 v1[0]=v2[0]= x1 + a;
1139                 
1140                 glColor4fv( colf );
1141                 glVertex2fv(v1); glVertex2fv(v2);
1142         }
1143         
1144         glEnd();
1145         glShadeModel(GL_FLAT);
1146         glDisable(GL_BLEND);
1147         
1148         /* outline */
1149         glColor4f(0.0, 0.0, 0.0, 1.0);
1150         fdrawbox(x1, y1, x1+sizex, y1+sizey);
1151         
1152         /* help lines */
1153         v1[0]= v2[0]=v3[0]= x1;
1154         v1[1]= y1;
1155         v1a[1]= y1+0.25f*sizey;
1156         v2[1]= y1+0.5f*sizey;
1157         v2a[1]= y1+0.75f*sizey;
1158         v3[1]= y1+sizey;
1159         
1160         
1161         cbd= coba->data;
1162         glBegin(GL_LINES);
1163         for(a=0; a<coba->tot; a++, cbd++) {
1164                 v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
1165                 
1166                 if(a==coba->cur) {
1167                         glColor3ub(0, 0, 0);
1168                         glVertex2fv(v1);
1169                         glVertex2fv(v3);
1170                         glEnd();
1171                         
1172                         setlinestyle(2);
1173                         glBegin(GL_LINES);
1174                         glColor3ub(255, 255, 255);
1175                         glVertex2fv(v1);
1176                         glVertex2fv(v3);
1177                         glEnd();
1178                         setlinestyle(0);
1179                         glBegin(GL_LINES);
1180                         
1181                         /* glColor3ub(0, 0, 0);
1182                         glVertex2fv(v1);
1183                         glVertex2fv(v1a);
1184                         glColor3ub(255, 255, 255);
1185                         glVertex2fv(v1a);
1186                         glVertex2fv(v2);
1187                         glColor3ub(0, 0, 0);
1188                         glVertex2fv(v2);
1189                         glVertex2fv(v2a);
1190                         glColor3ub(255, 255, 255);
1191                         glVertex2fv(v2a);
1192                         glVertex2fv(v3);
1193                         */
1194                 }
1195                 else {
1196                         glColor3ub(0, 0, 0);
1197                         glVertex2fv(v1);
1198                         glVertex2fv(v2);
1199                         
1200                         glColor3ub(255, 255, 255);
1201                         glVertex2fv(v2);
1202                         glVertex2fv(v3);
1203                 }       
1204         }
1205         glEnd();
1206
1207 }
1208
1209 void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect)
1210 {
1211         static GLuint displist=0;
1212         int a, old[8];
1213         GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f};
1214         float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f};
1215         float dir[4], size;
1216         
1217         /* store stuff */
1218         glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
1219                 
1220         /* backdrop */
1221         glColor3ubv((unsigned char*)wcol->inner);
1222         uiSetRoundBox(UI_CNR_ALL);
1223         uiDrawBox(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
1224         
1225         /* sphere color */
1226         glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
1227         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
1228         
1229         /* disable blender light */
1230         for(a=0; a<8; a++) {
1231                 old[a]= glIsEnabled(GL_LIGHT0+a);
1232                 glDisable(GL_LIGHT0+a);
1233         }
1234         
1235         /* own light */
1236         glEnable(GL_LIGHT7);
1237         glEnable(GL_LIGHTING);
1238         
1239         ui_get_but_vectorf(but, dir);
1240
1241         dir[3]= 0.0f;   /* glLight needs 4 args, 0.0 is sun */
1242         glLightfv(GL_LIGHT7, GL_POSITION, dir); 
1243         glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn); 
1244         glLightfv(GL_LIGHT7, GL_SPECULAR, vec0); 
1245         glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f);
1246         glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f);
1247         
1248         /* transform to button */
1249         glPushMatrix();
1250         glTranslatef(rect->xmin + 0.5f*(rect->xmax-rect->xmin), rect->ymin+ 0.5f*(rect->ymax-rect->ymin), 0.0f);
1251         
1252         if( rect->xmax-rect->xmin < rect->ymax-rect->ymin)
1253                 size= (rect->xmax-rect->xmin)/200.f;
1254         else
1255                 size= (rect->ymax-rect->ymin)/200.f;
1256         
1257         glScalef(size, size, size);
1258         
1259         if(displist==0) {
1260                 GLUquadricObj   *qobj;
1261                 
1262                 displist= glGenLists(1);
1263                 glNewList(displist, GL_COMPILE_AND_EXECUTE);
1264                 
1265                 qobj= gluNewQuadric();
1266                 gluQuadricDrawStyle(qobj, GLU_FILL); 
1267                 glShadeModel(GL_SMOOTH);
1268                 gluSphere( qobj, 100.0, 32, 24);
1269                 glShadeModel(GL_FLAT);
1270                 gluDeleteQuadric(qobj);  
1271                 
1272                 glEndList();
1273         }
1274         else glCallList(displist);
1275         
1276         /* restore */
1277         glDisable(GL_LIGHTING);
1278         glDisable(GL_CULL_FACE);
1279         glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); 
1280         glDisable(GL_LIGHT7);
1281         
1282         /* AA circle */
1283         glEnable(GL_BLEND);
1284         glEnable(GL_LINE_SMOOTH );
1285         glColor3ubv((unsigned char*)wcol->inner);
1286         glutil_draw_lined_arc(0.0f, M_PI*2.0, 100.0f, 32);
1287         glDisable(GL_BLEND);
1288         glDisable(GL_LINE_SMOOTH );
1289
1290         /* matrix after circle */
1291         glPopMatrix();
1292
1293         /* enable blender light */
1294         for(a=0; a<8; a++) {
1295                 if(old[a])
1296                         glEnable(GL_LIGHT0+a);
1297         }
1298 }
1299
1300 static void ui_draw_but_curve_grid(rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
1301 {
1302         float dx, dy, fx, fy;
1303         
1304         glBegin(GL_LINES);
1305         dx= step*zoomx;
1306         fx= rect->xmin + zoomx*(-offsx);
1307         if(fx > rect->xmin) fx -= dx*(floorf(fx-rect->xmin));
1308         while(fx < rect->xmax) {
1309                 glVertex2f(fx, rect->ymin); 
1310                 glVertex2f(fx, rect->ymax);
1311                 fx+= dx;
1312         }
1313         
1314         dy= step*zoomy;
1315         fy= rect->ymin + zoomy*(-offsy);
1316         if(fy > rect->ymin) fy -= dy*(floorf(fy-rect->ymin));
1317         while(fy < rect->ymax) {
1318                 glVertex2f(rect->xmin, fy); 
1319                 glVertex2f(rect->xmax, fy);
1320                 fy+= dy;
1321         }
1322         glEnd();
1323         
1324 }
1325
1326 static void glColor3ubvShade(unsigned char *col, int shade)
1327 {
1328         glColor3ub(col[0]-shade>0?col[0]-shade:0, 
1329                            col[1]-shade>0?col[1]-shade:0,
1330                            col[2]-shade>0?col[2]-shade:0);
1331 }
1332
1333 void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect)
1334 {
1335         CurveMapping *cumap;
1336         CurveMap *cuma;
1337         CurveMapPoint *cmp;
1338         float fx, fy, fac[2], zoomx, zoomy, offsx, offsy;
1339         GLint scissor[4];
1340         rcti scissor_new;
1341         int a;
1342
1343         cumap= (CurveMapping *)(but->editcumap? but->editcumap: but->poin);
1344         cuma= cumap->cm+cumap->cur;
1345         
1346         /* need scissor test, curve can draw outside of boundary */
1347         glGetIntegerv(GL_VIEWPORT, scissor);
1348         scissor_new.xmin= ar->winrct.xmin + rect->xmin;
1349         scissor_new.ymin= ar->winrct.ymin + rect->ymin;
1350         scissor_new.xmax= ar->winrct.xmin + rect->xmax;
1351         scissor_new.ymax= ar->winrct.ymin + rect->ymax;
1352         BLI_isect_rcti(&scissor_new, &ar->winrct, &scissor_new);
1353         glScissor(scissor_new.xmin, scissor_new.ymin, scissor_new.xmax-scissor_new.xmin, scissor_new.ymax-scissor_new.ymin);
1354         
1355         /* calculate offset and zoom */
1356         zoomx= (rect->xmax-rect->xmin-2.0f*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin);
1357         zoomy= (rect->ymax-rect->ymin-2.0f*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin);
1358         offsx= cumap->curr.xmin-but->aspect/zoomx;
1359         offsy= cumap->curr.ymin-but->aspect/zoomy;
1360         
1361         /* backdrop */
1362         if(cumap->flag & CUMA_DO_CLIP) {
1363                 glColor3ubvShade((unsigned char *)wcol->inner, -20);
1364                 glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1365                 glColor3ubv((unsigned char*)wcol->inner);
1366                 glRectf(rect->xmin + zoomx*(cumap->clipr.xmin-offsx),
1367                                 rect->ymin + zoomy*(cumap->clipr.ymin-offsy),
1368                                 rect->xmin + zoomx*(cumap->clipr.xmax-offsx),
1369                                 rect->ymin + zoomy*(cumap->clipr.ymax-offsy));
1370         }
1371         else {
1372                 glColor3ubv((unsigned char*)wcol->inner);
1373                 glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1374         }
1375                 
1376         /* grid, every .25 step */
1377         glColor3ubvShade((unsigned char *)wcol->inner, -16);
1378         ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f);
1379         /* grid, every 1.0 step */
1380         glColor3ubvShade((unsigned char *)wcol->inner, -24);
1381         ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f);
1382         /* axes */
1383         glColor3ubvShade((unsigned char *)wcol->inner, -50);
1384         glBegin(GL_LINES);
1385         glVertex2f(rect->xmin, rect->ymin + zoomy*(-offsy));
1386         glVertex2f(rect->xmax, rect->ymin + zoomy*(-offsy));
1387         glVertex2f(rect->xmin + zoomx*(-offsx), rect->ymin);
1388         glVertex2f(rect->xmin + zoomx*(-offsx), rect->ymax);
1389         glEnd();
1390         
1391         /* magic trigger for curve backgrounds */
1392         if (but->a1 != -1) {
1393                 if (but->a1 == UI_GRAD_H) {
1394                         rcti grid;
1395                         float col[3]= {0.0f, 0.0f, 0.0f}; /* dummy arg */
1396                         
1397                         grid.xmin = rect->xmin + zoomx*(-offsx);
1398                         grid.xmax = rect->xmax + zoomx*(-offsx);
1399                         grid.ymin = rect->ymin + zoomy*(-offsy);
1400                         grid.ymax = rect->ymax + zoomy*(-offsy);
1401                         
1402                         glEnable(GL_BLEND);
1403                         ui_draw_gradient(&grid, col, UI_GRAD_H, 0.5f);
1404                         glDisable(GL_BLEND);
1405                 }
1406         }
1407         
1408         
1409         /* cfra option */
1410         /* XXX 2.48
1411         if(cumap->flag & CUMA_DRAW_CFRA) {
1412                 glColor3ub(0x60, 0xc0, 0x40);
1413                 glBegin(GL_LINES);
1414                 glVertex2f(rect->xmin + zoomx*(cumap->sample[0]-offsx), rect->ymin);
1415                 glVertex2f(rect->xmin + zoomx*(cumap->sample[0]-offsx), rect->ymax);
1416                 glEnd();
1417         }*/
1418         /* sample option */
1419         /* XXX 2.48
1420          * if(cumap->flag & CUMA_DRAW_SAMPLE) {
1421                 if(cumap->cur==3) {
1422                         float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
1423                         glColor3ub(240, 240, 240);
1424                         
1425                         glBegin(GL_LINES);
1426                         glVertex2f(rect->xmin + zoomx*(lum-offsx), rect->ymin);
1427                         glVertex2f(rect->xmin + zoomx*(lum-offsx), rect->ymax);
1428                         glEnd();
1429                 }
1430                 else {
1431                         if(cumap->cur==0)
1432                                 glColor3ub(240, 100, 100);
1433                         else if(cumap->cur==1)
1434                                 glColor3ub(100, 240, 100);
1435                         else
1436                                 glColor3ub(100, 100, 240);
1437                         
1438                         glBegin(GL_LINES);
1439                         glVertex2f(rect->xmin + zoomx*(cumap->sample[cumap->cur]-offsx), rect->ymin);
1440                         glVertex2f(rect->xmin + zoomx*(cumap->sample[cumap->cur]-offsx), rect->ymax);
1441                         glEnd();
1442                 }
1443         }*/
1444         
1445         /* the curve */
1446         glColor3ubv((unsigned char*)wcol->item);
1447         glEnable(GL_LINE_SMOOTH);
1448         glEnable(GL_BLEND);
1449         glBegin(GL_LINE_STRIP);
1450         
1451         if(cuma->table==NULL)
1452                 curvemapping_changed(cumap, 0); /* 0 = no remove doubles */
1453         cmp= cuma->table;
1454         
1455         /* first point */
1456         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
1457                 glVertex2f(rect->xmin, rect->ymin + zoomy*(cmp[0].y-offsy));
1458         else {
1459                 fx= rect->xmin + zoomx*(cmp[0].x-offsx + cuma->ext_in[0]);
1460                 fy= rect->ymin + zoomy*(cmp[0].y-offsy + cuma->ext_in[1]);
1461                 glVertex2f(fx, fy);
1462         }
1463         for(a=0; a<=CM_TABLE; a++) {
1464                 fx= rect->xmin + zoomx*(cmp[a].x-offsx);
1465                 fy= rect->ymin + zoomy*(cmp[a].y-offsy);
1466                 glVertex2f(fx, fy);
1467         }
1468         /* last point */
1469         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
1470                 glVertex2f(rect->xmax, rect->ymin + zoomy*(cmp[CM_TABLE].y-offsy));     
1471         else {
1472                 fx= rect->xmin + zoomx*(cmp[CM_TABLE].x-offsx - cuma->ext_out[0]);
1473                 fy= rect->ymin + zoomy*(cmp[CM_TABLE].y-offsy - cuma->ext_out[1]);
1474                 glVertex2f(fx, fy);
1475         }
1476         glEnd();
1477         glDisable(GL_LINE_SMOOTH);
1478         glDisable(GL_BLEND);
1479
1480         /* the points, use aspect to make them visible on edges */
1481         cmp= cuma->curve;
1482         glPointSize(3.0f);
1483         bglBegin(GL_POINTS);
1484         for(a=0; a<cuma->totpoint; a++) {
1485                 if(cmp[a].flag & SELECT)
1486                         UI_ThemeColor(TH_TEXT_HI);
1487                 else
1488                         UI_ThemeColor(TH_TEXT);
1489                 fac[0]= rect->xmin + zoomx*(cmp[a].x-offsx);
1490                 fac[1]= rect->ymin + zoomy*(cmp[a].y-offsy);
1491                 bglVertex2fv(fac);
1492         }
1493         bglEnd();
1494         glPointSize(1.0f);
1495         
1496         /* restore scissortest */
1497         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
1498
1499         /* outline */
1500         glColor3ubv((unsigned char*)wcol->outline);
1501         fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1502 }
1503
1504
1505 /* ****************************************************** */
1506
1507
1508 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1509 {
1510         glEnable(GL_BLEND);
1511         glShadeModel(GL_SMOOTH);
1512         
1513         /* right quad */
1514         glBegin(GL_POLYGON);
1515         glColor4ub(0, 0, 0, alpha);
1516         glVertex2f(maxx, miny);
1517         glVertex2f(maxx, maxy-0.3f*shadsize);
1518         glColor4ub(0, 0, 0, 0);
1519         glVertex2f(maxx+shadsize, maxy-0.75f*shadsize);
1520         glVertex2f(maxx+shadsize, miny);
1521         glEnd();
1522         
1523         /* corner shape */
1524         glBegin(GL_POLYGON);
1525         glColor4ub(0, 0, 0, alpha);
1526         glVertex2f(maxx, miny);
1527         glColor4ub(0, 0, 0, 0);
1528         glVertex2f(maxx+shadsize, miny);
1529         glVertex2f(maxx+0.7f*shadsize, miny-0.7f*shadsize);
1530         glVertex2f(maxx, miny-shadsize);
1531         glEnd();
1532         
1533         /* bottom quad */               
1534         glBegin(GL_POLYGON);
1535         glColor4ub(0, 0, 0, alpha);
1536         glVertex2f(minx+0.3f*shadsize, miny);
1537         glVertex2f(maxx, miny);
1538         glColor4ub(0, 0, 0, 0);
1539         glVertex2f(maxx, miny-shadsize);
1540         glVertex2f(minx+0.5f*shadsize, miny-shadsize);
1541         glEnd();
1542         
1543         glDisable(GL_BLEND);
1544         glShadeModel(GL_FLAT);
1545 }
1546
1547 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1548 {
1549         /* accumulated outline boxes to make shade not linear, is more pleasant */
1550         ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20*alpha)>>8);
1551         ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40*alpha)>>8);
1552         ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80*alpha)>>8);
1553         
1554 }
1555
1556
1557 void ui_dropshadow(rctf *rct, float radius, float aspect, int UNUSED(select))
1558 {
1559         int i;
1560         float rad;
1561         float a;
1562         char alpha= 2;
1563         
1564         glEnable(GL_BLEND);
1565         
1566         if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
1567                 rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
1568         else
1569                 rad= radius;
1570
1571         i= 12;
1572 #if 0
1573         if(select) {
1574                 a= i*aspect; /* same as below */
1575         }
1576         else
1577 #endif
1578         {
1579                 a= i*aspect;
1580         }
1581
1582         for(; i--; a-=aspect) {
1583                 /* alpha ranges from 2 to 20 or so */
1584                 glColor4ub(0, 0, 0, alpha);
1585                 alpha+= 2;
1586                 
1587                 uiDrawBox(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
1588         }
1589         
1590         /* outline emphasis */
1591         glEnable( GL_LINE_SMOOTH );
1592         glColor4ub(0, 0, 0, 100);
1593         uiDrawBox(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius+0.5f);
1594         glDisable( GL_LINE_SMOOTH );
1595         
1596         glDisable(GL_BLEND);
1597 }
1598