Assorted fixes - compile + drivers:
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <string.h>
32
33 #include "DNA_color_types.h"
34 #include "DNA_listBase.h"
35 #include "DNA_object_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_texture_types.h"
38 #include "DNA_userdef_types.h"
39
40 #include "BLI_math.h"
41
42 #include "BKE_colortools.h"
43 #include "BKE_texture.h"
44 #include "BKE_utildefines.h"
45
46 #include "IMB_imbuf.h"
47 #include "IMB_imbuf_types.h"
48
49 #include "BIF_gl.h"
50 #include "BIF_glutil.h"
51
52 #include "UI_interface.h"
53 #include "UI_interface_icons.h"
54
55 #include "interface_intern.h"
56
57 #define UI_RB_ALPHA 16
58 #define UI_DISABLED_ALPHA_OFFS  -160
59
60 static int roundboxtype= 15;
61
62 void uiSetRoundBox(int type)
63 {
64         /* Not sure the roundbox function is the best place to change this
65          * if this is undone, its not that big a deal, only makes curves edges
66          * square for the  */
67         roundboxtype= type;
68
69         /* flags to set which corners will become rounded:
70
71         1------2
72         |      |
73         8------4
74         */
75         
76 }
77
78 int uiGetRoundBox(void)
79 {
80         return roundboxtype;
81 }
82
83 void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad)
84 {
85         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
86                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
87         int a;
88         
89         /* mult */
90         for(a=0; a<7; a++) {
91                 vec[a][0]*= rad; vec[a][1]*= rad;
92         }
93
94         glBegin(mode);
95
96         /* start with corner right-bottom */
97         if(roundboxtype & 4) {
98                 glVertex2f(maxx-rad, miny);
99                 for(a=0; a<7; a++) {
100                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
101                 }
102                 glVertex2f(maxx, miny+rad);
103         }
104         else glVertex2f(maxx, miny);
105         
106         /* corner right-top */
107         if(roundboxtype & 2) {
108                 glVertex2f(maxx, maxy-rad);
109                 for(a=0; a<7; a++) {
110                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
111                 }
112                 glVertex2f(maxx-rad, maxy);
113         }
114         else glVertex2f(maxx, maxy);
115         
116         /* corner left-top */
117         if(roundboxtype & 1) {
118                 glVertex2f(minx+rad, maxy);
119                 for(a=0; a<7; a++) {
120                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
121                 }
122                 glVertex2f(minx, maxy-rad);
123         }
124         else glVertex2f(minx, maxy);
125         
126         /* corner left-bottom */
127         if(roundboxtype & 8) {
128                 glVertex2f(minx, miny+rad);
129                 for(a=0; a<7; a++) {
130                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
131                 }
132                 glVertex2f(minx+rad, miny);
133         }
134         else glVertex2f(minx, miny);
135         
136         glEnd();
137 }
138
139 static void round_box_shade_col(float *col1, float *col2, float fac)
140 {
141         float col[3];
142
143         col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
144         col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
145         col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
146         
147         glColor3fv(col);
148 }
149
150
151 /* linear horizontal shade within button or in outline */
152 /* view2d scrollers use it */
153 void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
154 {
155         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
156                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
157         float div= maxy-miny;
158         float coltop[3], coldown[3], color[4];
159         int a;
160         
161         /* mult */
162         for(a=0; a<7; a++) {
163                 vec[a][0]*= rad; vec[a][1]*= rad;
164         }
165         /* get current color, needs to be outside of glBegin/End */
166         glGetFloatv(GL_CURRENT_COLOR, color);
167
168         /* 'shade' defines strength of shading */       
169         coltop[0]= color[0]+shadetop; if(coltop[0]>1.0) coltop[0]= 1.0;
170         coltop[1]= color[1]+shadetop; if(coltop[1]>1.0) coltop[1]= 1.0;
171         coltop[2]= color[2]+shadetop; if(coltop[2]>1.0) coltop[2]= 1.0;
172         coldown[0]= color[0]+shadedown; if(coldown[0]<0.0) coldown[0]= 0.0;
173         coldown[1]= color[1]+shadedown; if(coldown[1]<0.0) coldown[1]= 0.0;
174         coldown[2]= color[2]+shadedown; if(coldown[2]<0.0) coldown[2]= 0.0;
175
176         glShadeModel(GL_SMOOTH);
177         glBegin(mode);
178
179         /* start with corner right-bottom */
180         if(roundboxtype & 4) {
181                 
182                 round_box_shade_col(coltop, coldown, 0.0);
183                 glVertex2f(maxx-rad, miny);
184                 
185                 for(a=0; a<7; a++) {
186                         round_box_shade_col(coltop, coldown, vec[a][1]/div);
187                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
188                 }
189                 
190                 round_box_shade_col(coltop, coldown, rad/div);
191                 glVertex2f(maxx, miny+rad);
192         }
193         else {
194                 round_box_shade_col(coltop, coldown, 0.0);
195                 glVertex2f(maxx, miny);
196         }
197         
198         /* corner right-top */
199         if(roundboxtype & 2) {
200                 
201                 round_box_shade_col(coltop, coldown, (div-rad)/div);
202                 glVertex2f(maxx, maxy-rad);
203                 
204                 for(a=0; a<7; a++) {
205                         round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div);
206                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
207                 }
208                 round_box_shade_col(coltop, coldown, 1.0);
209                 glVertex2f(maxx-rad, maxy);
210         }
211         else {
212                 round_box_shade_col(coltop, coldown, 1.0);
213                 glVertex2f(maxx, maxy);
214         }
215         
216         /* corner left-top */
217         if(roundboxtype & 1) {
218                 
219                 round_box_shade_col(coltop, coldown, 1.0);
220                 glVertex2f(minx+rad, maxy);
221                 
222                 for(a=0; a<7; a++) {
223                         round_box_shade_col(coltop, coldown, (div-vec[a][1])/div);
224                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
225                 }
226                 
227                 round_box_shade_col(coltop, coldown, (div-rad)/div);
228                 glVertex2f(minx, maxy-rad);
229         }
230         else {
231                 round_box_shade_col(coltop, coldown, 1.0);
232                 glVertex2f(minx, maxy);
233         }
234         
235         /* corner left-bottom */
236         if(roundboxtype & 8) {
237                 
238                 round_box_shade_col(coltop, coldown, rad/div);
239                 glVertex2f(minx, miny+rad);
240                 
241                 for(a=0; a<7; a++) {
242                         round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div);
243                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
244                 }
245                 
246                 round_box_shade_col(coltop, coldown, 0.0);
247                 glVertex2f(minx+rad, miny);
248         }
249         else {
250                 round_box_shade_col(coltop, coldown, 0.0);
251                 glVertex2f(minx, miny);
252         }
253         
254         glEnd();
255         glShadeModel(GL_FLAT);
256 }
257
258 /* linear vertical shade within button or in outline */
259 /* view2d scrollers use it */
260 void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight)
261 {
262         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
263                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
264         float div= maxx-minx;
265         float colLeft[3], colRight[3], color[4];
266         int a;
267         
268         /* mult */
269         for(a=0; a<7; a++) {
270                 vec[a][0]*= rad; vec[a][1]*= rad;
271         }
272         /* get current color, needs to be outside of glBegin/End */
273         glGetFloatv(GL_CURRENT_COLOR, color);
274
275         /* 'shade' defines strength of shading */       
276         colLeft[0]= color[0]+shadeLeft; if(colLeft[0]>1.0) colLeft[0]= 1.0;
277         colLeft[1]= color[1]+shadeLeft; if(colLeft[1]>1.0) colLeft[1]= 1.0;
278         colLeft[2]= color[2]+shadeLeft; if(colLeft[2]>1.0) colLeft[2]= 1.0;
279         colRight[0]= color[0]+shadeRight; if(colRight[0]<0.0) colRight[0]= 0.0;
280         colRight[1]= color[1]+shadeRight; if(colRight[1]<0.0) colRight[1]= 0.0;
281         colRight[2]= color[2]+shadeRight; if(colRight[2]<0.0) colRight[2]= 0.0;
282
283         glShadeModel(GL_SMOOTH);
284         glBegin(mode);
285
286         /* start with corner right-bottom */
287         if(roundboxtype & 4) {
288                 round_box_shade_col(colLeft, colRight, 0.0);
289                 glVertex2f(maxx-rad, miny);
290                 
291                 for(a=0; a<7; a++) {
292                         round_box_shade_col(colLeft, colRight, vec[a][0]/div);
293                         glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
294                 }
295                 
296                 round_box_shade_col(colLeft, colRight, rad/div);
297                 glVertex2f(maxx, miny+rad);
298         }
299         else {
300                 round_box_shade_col(colLeft, colRight, 0.0);
301                 glVertex2f(maxx, miny);
302         }
303         
304         /* corner right-top */
305         if(roundboxtype & 2) {
306                 round_box_shade_col(colLeft, colRight, 0.0);
307                 glVertex2f(maxx, maxy-rad);
308                 
309                 for(a=0; a<7; a++) {
310                         
311                         round_box_shade_col(colLeft, colRight, (div-rad-vec[a][0])/div);
312                         glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
313                 }
314                 round_box_shade_col(colLeft, colRight, (div-rad)/div);
315                 glVertex2f(maxx-rad, maxy);
316         }
317         else {
318                 round_box_shade_col(colLeft, colRight, 0.0);
319                 glVertex2f(maxx, maxy);
320         }
321         
322         /* corner left-top */
323         if(roundboxtype & 1) {
324                 round_box_shade_col(colLeft, colRight, (div-rad)/div);
325                 glVertex2f(minx+rad, maxy);
326                 
327                 for(a=0; a<7; a++) {
328                         round_box_shade_col(colLeft, colRight, (div-rad+vec[a][0])/div);
329                         glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
330                 }
331                 
332                 round_box_shade_col(colLeft, colRight, 1.0);
333                 glVertex2f(minx, maxy-rad);
334         }
335         else {
336                 round_box_shade_col(colLeft, colRight, 1.0);
337                 glVertex2f(minx, maxy);
338         }
339         
340         /* corner left-bottom */
341         if(roundboxtype & 8) {
342                 round_box_shade_col(colLeft, colRight, 1.0);
343                 glVertex2f(minx, miny+rad);
344                 
345                 for(a=0; a<7; a++) {
346                         round_box_shade_col(colLeft, colRight, (vec[a][0])/div);
347                         glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
348                 }
349                 
350                 round_box_shade_col(colLeft, colRight, 1.0);
351                 glVertex2f(minx+rad, miny);
352         }
353         else {
354                 round_box_shade_col(colLeft, colRight, 1.0);
355                 glVertex2f(minx, miny);
356         }
357         
358         glEnd();
359         glShadeModel(GL_FLAT);
360 }
361
362 /* plain antialiased unfilled rectangle */
363 void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
364 {
365         float color[4];
366         
367         if(roundboxtype & UI_RB_ALPHA) {
368                 glGetFloatv(GL_CURRENT_COLOR, color);
369                 color[3]= 0.5;
370                 glColor4fv(color);
371                 glEnable( GL_BLEND );
372         }
373         
374         /* set antialias line */
375         glEnable( GL_LINE_SMOOTH );
376         glEnable( GL_BLEND );
377
378         gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
379    
380         glDisable( GL_BLEND );
381         glDisable( GL_LINE_SMOOTH );
382 }
383
384 /* plain fake antialiased unfilled round rectangle */
385 void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
386 {
387         float color[4], alpha;
388         float raddiff;
389         int i, passes=4;
390         
391         /* get the colour and divide up the alpha */
392         glGetFloatv(GL_CURRENT_COLOR, color);
393         alpha = 1; //color[3];
394         color[3]= 0.5*alpha/(float)passes;
395         glColor4fv(color);
396         
397         /* set the 'jitter amount' */
398         raddiff = (1/(float)passes) * asp;
399         
400         glEnable( GL_BLEND );
401         
402         /* draw lots of lines on top of each other */
403         for (i=passes; i>=(-passes); i--) {
404                 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad+(i*raddiff));
405         }
406         
407         glDisable( GL_BLEND );
408         
409         color[3] = alpha;
410         glColor4fv(color);
411 }
412
413 /* (old, used in outliner) plain antialiased filled box */
414 void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
415 {
416         float color[4];
417         
418         if(roundboxtype & UI_RB_ALPHA) {
419                 glGetFloatv(GL_CURRENT_COLOR, color);
420                 color[3]= 0.5;
421                 glColor4fv(color);
422                 glEnable( GL_BLEND );
423         }
424         
425         /* solid part */
426         gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
427         
428         /* set antialias line */
429         glEnable( GL_LINE_SMOOTH );
430         glEnable( GL_BLEND );
431         
432         gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
433         
434         glDisable( GL_BLEND );
435         glDisable( GL_LINE_SMOOTH );
436 }
437
438
439 /* ************** generic embossed rect, for window sliders etc ************* */
440
441
442 /* text_draw.c uses this */
443 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
444 {
445         
446         /* below */
447         if(sel) glColor3ub(200,200,200);
448         else glColor3ub(50,50,50);
449         fdrawline(x1, y1, x2, y1);
450
451         /* right */
452         fdrawline(x2, y1, x2, y2);
453         
454         /* top */
455         if(sel) glColor3ub(50,50,50);
456         else glColor3ub(200,200,200);
457         fdrawline(x1, y2, x2, y2);
458
459         /* left */
460         fdrawline(x1, y1, x1, y2);
461         
462 }
463
464 /* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */
465
466 void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect)
467 {
468         extern char datatoc_splash_png[];
469         extern int datatoc_splash_png_size;
470         ImBuf *ibuf;
471         //GLint scissor[4];
472         //int w, h;
473         
474         /* hardcoded to splash, loading and freeing every draw, eek! */
475         ibuf= IMB_ibImageFromMemory((int *)datatoc_splash_png, datatoc_splash_png_size, IB_rect);
476
477         if (!ibuf) return;
478         
479         /* scissor doesn't seem to be doing the right thing...?
480         //glColor4f(1.0, 0.f, 0.f, 1.f);
481         //fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax)
482
483         w = (rect->xmax - rect->xmin);
484         h = (rect->ymax - rect->ymin);
485         // prevent drawing outside widget area
486         glGetIntegerv(GL_SCISSOR_BOX, scissor);
487         glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin + rect->ymin, w, h);
488         */
489         
490         glEnable(GL_BLEND);
491         glColor4f(0.0, 0.0, 0.0, 0.0);
492         
493         glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
494         //glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
495         
496         glDisable(GL_BLEND);
497         
498         /* 
499         // restore scissortest
500         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
501         */
502         
503         IMB_freeImBuf(ibuf);
504 }
505
506 #if 0
507 #ifdef INTERNATIONAL
508 static void ui_draw_but_CHARTAB(uiBut *but)
509 {
510         /* XXX 2.50 bad global access */
511         /* Some local variables */
512         float sx, sy, ex, ey;
513         float width, height;
514         float butw, buth;
515         int x, y, cs;
516         wchar_t wstr[2];
517         unsigned char ustr[16];
518         PackedFile *pf;
519         int result = 0;
520         int charmax = G.charmax;
521         
522         /* <builtin> font in use. There are TTF <builtin> and non-TTF <builtin> fonts */
523         if(!strcmp(G.selfont->name, "<builtin>"))
524         {
525                 if(G.ui_international == TRUE)
526                 {
527                         charmax = 0xff;
528                 }
529                 else
530                 {
531                         charmax = 0xff;
532                 }
533         }
534
535         /* Category list exited without selecting the area */
536         if(G.charmax == 0)
537                 charmax = G.charmax = 0xffff;
538
539         /* Calculate the size of the button */
540         width = abs(rect->xmax - rect->xmin);
541         height = abs(rect->ymax - rect->ymin);
542         
543         butw = floor(width / 12);
544         buth = floor(height / 6);
545         
546         /* Initialize variables */
547         sx = rect->xmin;
548         ex = rect->xmin + butw;
549         sy = rect->ymin + height - buth;
550         ey = rect->ymin + height;
551
552         cs = G.charstart;
553
554         /* Set the font, in case it is not <builtin> font */
555         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
556         {
557                 char tmpStr[256];
558
559                 // Is the font file packed, if so then use the packed file
560                 if(G.selfont->packedfile)
561                 {
562                         pf = G.selfont->packedfile;             
563                         FTF_SetFont(pf->data, pf->size, 14.0);
564                 }
565                 else
566                 {
567                         int err;
568
569                         strcpy(tmpStr, G.selfont->name);
570                         BLI_convertstringcode(tmpStr, G.sce);
571                         err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
572                 }
573         }
574         else
575         {
576                 if(G.ui_international == TRUE)
577                 {
578                         FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0);
579                 }
580         }
581
582         /* Start drawing the button itself */
583         glShadeModel(GL_SMOOTH);
584
585         glColor3ub(200,  200,  200);
586         glRectf((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax));
587
588         glColor3ub(0,  0,  0);
589         for(y = 0; y < 6; y++)
590         {
591                 // Do not draw more than the category allows
592                 if(cs > charmax) break;
593
594                 for(x = 0; x < 12; x++)
595                 {
596                         // Do not draw more than the category allows
597                         if(cs > charmax) break;
598
599                         // Draw one grid cell
600                         glBegin(GL_LINE_LOOP);
601                                 glVertex2f(sx, sy);
602                                 glVertex2f(ex, sy);
603                                 glVertex2f(ex, ey);
604                                 glVertex2f(sx, ey);                             
605                         glEnd();        
606
607                         // Draw character inside the cell
608                         memset(wstr, 0, sizeof(wchar_t)*2);
609                         memset(ustr, 0, 16);
610
611                         // Set the font to be either unicode or <builtin>                               
612                         wstr[0] = cs;
613                         if(strcmp(G.selfont->name, "<builtin>"))
614                         {
615                                 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
616                         }
617                         else
618                         {
619                                 if(G.ui_international == TRUE)
620                                 {
621                                         wcs2utf8s((char *)ustr, (wchar_t *)wstr);
622                                 }
623                                 else
624                                 {
625                                         ustr[0] = cs;
626                                         ustr[1] = 0;
627                                 }
628                         }
629
630                         if((G.selfont && strcmp(G.selfont->name, "<builtin>")) || (G.selfont && !strcmp(G.selfont->name, "<builtin>") && G.ui_international == TRUE))
631                         {
632                                 float wid;
633                                 float llx, lly, llz, urx, ury, urz;
634                                 float dx, dy;
635                                 float px, py;
636         
637                                 // Calculate the position
638                                 wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
639                                 FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
640                                 dx = urx-llx;
641                                 dy = ury-lly;
642
643                                 // This isn't fully functional since the but->aspect isn't working like I suspected
644                                 px = sx + ((butw/but->aspect)-dx)/2;
645                                 py = sy + ((buth/but->aspect)-dy)/2;
646
647                                 // Set the position and draw the character
648                                 ui_rasterpos_safe(px, py, but->aspect);
649                                 FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
650                         }
651                         else
652                         {
653                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
654                                 UI_DrawString(but->font, (char *) ustr, 0);
655                         }
656         
657                         // Calculate the next position and character
658                         sx += butw; ex +=butw;
659                         cs++;
660                 }
661                 /* Add the y position and reset x position */
662                 sy -= buth; 
663                 ey -= buth;
664                 sx = rect->xmin;
665                 ex = rect->xmin + butw;
666         }       
667         glShadeModel(GL_FLAT);
668
669         /* Return Font Settings to original */
670         if(U.fontsize && U.fontname[0])
671         {
672                 result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize);
673         }
674         else if (U.fontsize)
675         {
676                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
677         }
678
679         if (result == 0)
680         {
681                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
682         }
683         
684         /* resets the font size */
685         if(G.ui_international == TRUE)
686         {
687                 // uiSetCurFont(but->block, UI_HELV);
688         }
689 }
690
691 #endif // INTERNATIONAL
692 #endif
693
694 void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *wcol, rcti *rect)
695 {
696         ColorBand *coba;
697         CBData *cbd;
698         float x1, y1, sizex, sizey;
699         float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
700         int a;
701         float pos, colf[4];
702                 
703         coba= (ColorBand *)(but->editcoba? but->editcoba: but->poin);
704         if(coba==NULL) return;
705         
706         x1= rect->xmin;
707         y1= rect->ymin;
708         sizex= rect->xmax-x1;
709         sizey= rect->ymax-y1;
710         
711         /* first background, to show tranparency */
712         dx= sizex/12.0;
713         v1[0]= x1;
714         for(a=0; a<12; a++) {
715                 if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
716                 glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey);
717                 if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
718                 glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey);
719                 v1[0]+= dx;
720         }
721         
722         glShadeModel(GL_FLAT);
723         glEnable(GL_BLEND);
724         
725         cbd= coba->data;
726         
727         v1[0]= v2[0]= x1;
728         v1[1]= y1;
729         v2[1]= y1+sizey;
730         
731         glBegin(GL_QUAD_STRIP);
732         
733         glColor4fv( &cbd->r );
734         glVertex2fv(v1); glVertex2fv(v2);
735         
736         for( a = 1; a < sizex; a++ ) {
737                 pos = ((float)a) / (sizex-1);
738                 do_colorband( coba, pos, colf );
739                 
740                 v1[0]=v2[0]= x1 + a;
741                 
742                 glColor4fv( colf );
743                 glVertex2fv(v1); glVertex2fv(v2);
744         }
745         
746         glEnd();
747         glShadeModel(GL_FLAT);
748         glDisable(GL_BLEND);
749         
750         /* outline */
751         v1[0]= x1; v1[1]= y1;
752         
753         cpack(0x0);
754         glBegin(GL_LINE_LOOP);
755         glVertex2fv(v1);
756         v1[0]+= sizex;
757         glVertex2fv(v1);
758         v1[1]+= sizey;
759         glVertex2fv(v1);
760         v1[0]-= sizex;
761         glVertex2fv(v1);
762         glEnd();
763         
764         
765         /* help lines */
766         v1[0]= v2[0]=v3[0]= x1;
767         v1[1]= y1;
768         v1a[1]= y1+0.25*sizey;
769         v2[1]= y1+0.5*sizey;
770         v2a[1]= y1+0.75*sizey;
771         v3[1]= y1+sizey;
772         
773         
774         cbd= coba->data;
775         glBegin(GL_LINES);
776         for(a=0; a<coba->tot; a++, cbd++) {
777                 v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
778                 
779                 if(a==coba->cur) {
780                         glColor3ub(0, 0, 0);
781                         glVertex2fv(v1);
782                         glVertex2fv(v3);
783                         glEnd();
784                         
785                         setlinestyle(2);
786                         glBegin(GL_LINES);
787                         glColor3ub(255, 255, 255);
788                         glVertex2fv(v1);
789                         glVertex2fv(v3);
790                         glEnd();
791                         setlinestyle(0);
792                         glBegin(GL_LINES);
793                         
794                         /* glColor3ub(0, 0, 0);
795                         glVertex2fv(v1);
796                         glVertex2fv(v1a);
797                         glColor3ub(255, 255, 255);
798                         glVertex2fv(v1a);
799                         glVertex2fv(v2);
800                         glColor3ub(0, 0, 0);
801                         glVertex2fv(v2);
802                         glVertex2fv(v2a);
803                         glColor3ub(255, 255, 255);
804                         glVertex2fv(v2a);
805                         glVertex2fv(v3);
806                         */
807                 }
808                 else {
809                         glColor3ub(0, 0, 0);
810                         glVertex2fv(v1);
811                         glVertex2fv(v2);
812                         
813                         glColor3ub(255, 255, 255);
814                         glVertex2fv(v2);
815                         glVertex2fv(v3);
816                 }       
817         }
818         glEnd();
819 }
820
821 void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect)
822 {
823         static GLuint displist=0;
824         int a, old[8];
825         GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f};
826         float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f};
827         float dir[4], size;
828         
829         /* store stuff */
830         glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
831                 
832         /* backdrop */
833         glColor3ubv((unsigned char*)wcol->inner);
834         uiSetRoundBox(15);
835         gl_round_box(GL_POLYGON, rect->xmin, rect->ymin, rect->xmax, rect->ymax, 5.0f);
836         
837         /* sphere color */
838         glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
839         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
840         
841         /* disable blender light */
842         for(a=0; a<8; a++) {
843                 old[a]= glIsEnabled(GL_LIGHT0+a);
844                 glDisable(GL_LIGHT0+a);
845         }
846         
847         /* own light */
848         glEnable(GL_LIGHT7);
849         glEnable(GL_LIGHTING);
850         
851         ui_get_but_vectorf(but, dir);
852
853         dir[3]= 0.0f;   /* glLight needs 4 args, 0.0 is sun */
854         glLightfv(GL_LIGHT7, GL_POSITION, dir); 
855         glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn); 
856         glLightfv(GL_LIGHT7, GL_SPECULAR, vec0); 
857         glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f);
858         glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f);
859         
860         /* transform to button */
861         glPushMatrix();
862         glTranslatef(rect->xmin + 0.5f*(rect->xmax-rect->xmin), rect->ymin+ 0.5f*(rect->ymax-rect->ymin), 0.0f);
863         
864         if( rect->xmax-rect->xmin < rect->ymax-rect->ymin)
865                 size= (rect->xmax-rect->xmin)/200.f;
866         else
867                 size= (rect->ymax-rect->ymin)/200.f;
868         
869         glScalef(size, size, size);
870         
871         if(displist==0) {
872                 GLUquadricObj   *qobj;
873                 
874                 displist= glGenLists(1);
875                 glNewList(displist, GL_COMPILE_AND_EXECUTE);
876                 
877                 qobj= gluNewQuadric();
878                 gluQuadricDrawStyle(qobj, GLU_FILL); 
879                 glShadeModel(GL_SMOOTH);
880                 gluSphere( qobj, 100.0, 32, 24);
881                 glShadeModel(GL_FLAT);
882                 gluDeleteQuadric(qobj);  
883                 
884                 glEndList();
885         }
886         else glCallList(displist);
887         
888         /* restore */
889         glDisable(GL_LIGHTING);
890         glDisable(GL_CULL_FACE);
891         glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); 
892         glDisable(GL_LIGHT7);
893         
894         /* AA circle */
895         glEnable(GL_BLEND);
896         glEnable(GL_LINE_SMOOTH );
897         glColor3ubv((unsigned char*)wcol->inner);
898         glutil_draw_lined_arc(0.0f, M_PI*2.0, 100.0f, 32);
899         glDisable(GL_BLEND);
900         glDisable(GL_LINE_SMOOTH );
901
902         /* matrix after circle */
903         glPopMatrix();
904
905         /* enable blender light */
906         for(a=0; a<8; a++) {
907                 if(old[a])
908                         glEnable(GL_LIGHT0+a);
909         }
910 }
911
912 static void ui_draw_but_curve_grid(rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step)
913 {
914         float dx, dy, fx, fy;
915         
916         glBegin(GL_LINES);
917         dx= step*zoomx;
918         fx= rect->xmin + zoomx*(-offsx);
919         if(fx > rect->xmin) fx -= dx*( floor(fx-rect->xmin));
920         while(fx < rect->xmax) {
921                 glVertex2f(fx, rect->ymin); 
922                 glVertex2f(fx, rect->ymax);
923                 fx+= dx;
924         }
925         
926         dy= step*zoomy;
927         fy= rect->ymin + zoomy*(-offsy);
928         if(fy > rect->ymin) fy -= dy*( floor(fy-rect->ymin));
929         while(fy < rect->ymax) {
930                 glVertex2f(rect->xmin, fy); 
931                 glVertex2f(rect->xmax, fy);
932                 fy+= dy;
933         }
934         glEnd();
935         
936 }
937
938 static void glColor3ubvShade(char *col, int shade)
939 {
940         glColor3ub(col[0]-shade>0?col[0]-shade:0, 
941                            col[1]-shade>0?col[1]-shade:0,
942                            col[2]-shade>0?col[2]-shade:0);
943 }
944
945 void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect)
946 {
947         CurveMapping *cumap;
948         CurveMap *cuma;
949         CurveMapPoint *cmp;
950         float fx, fy, fac[2], zoomx, zoomy, offsx, offsy;
951         GLint scissor[4];
952         int a;
953
954         cumap= (CurveMapping *)(but->editcumap? but->editcumap: but->poin);
955         cuma= cumap->cm+cumap->cur;
956         
957         /* need scissor test, curve can draw outside of boundary */
958         glGetIntegerv(GL_VIEWPORT, scissor);
959         glScissor(ar->winrct.xmin + rect->xmin, ar->winrct.ymin+rect->ymin, rect->xmax-rect->xmin, rect->ymax-rect->ymin);
960         
961         /* calculate offset and zoom */
962         zoomx= (rect->xmax-rect->xmin-2.0*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin);
963         zoomy= (rect->ymax-rect->ymin-2.0*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin);
964         offsx= cumap->curr.xmin-but->aspect/zoomx;
965         offsy= cumap->curr.ymin-but->aspect/zoomy;
966         
967         /* backdrop */
968         if(cumap->flag & CUMA_DO_CLIP) {
969                 glColor3ubvShade(wcol->inner, -20);
970                 glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
971                 glColor3ubv((unsigned char*)wcol->inner);
972                 glRectf(rect->xmin + zoomx*(cumap->clipr.xmin-offsx),
973                                 rect->ymin + zoomy*(cumap->clipr.ymin-offsy),
974                                 rect->xmin + zoomx*(cumap->clipr.xmax-offsx),
975                                 rect->ymin + zoomy*(cumap->clipr.ymax-offsy));
976         }
977         else {
978                 glColor3ubv((unsigned char*)wcol->inner);
979                 glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
980         }
981         
982         /* grid, every .25 step */
983         glColor3ubvShade(wcol->inner, -16);
984         ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f);
985         /* grid, every 1.0 step */
986         glColor3ubvShade(wcol->inner, -24);
987         ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f);
988         /* axes */
989         glColor3ubvShade(wcol->inner, -50);
990         glBegin(GL_LINES);
991         glVertex2f(rect->xmin, rect->ymin + zoomy*(-offsy));
992         glVertex2f(rect->xmax, rect->ymin + zoomy*(-offsy));
993         glVertex2f(rect->xmin + zoomx*(-offsx), rect->ymin);
994         glVertex2f(rect->xmin + zoomx*(-offsx), rect->ymax);
995         glEnd();
996         
997         /* cfra option */
998         /* XXX 2.48
999         if(cumap->flag & CUMA_DRAW_CFRA) {
1000                 glColor3ub(0x60, 0xc0, 0x40);
1001                 glBegin(GL_LINES);
1002                 glVertex2f(rect->xmin + zoomx*(cumap->sample[0]-offsx), rect->ymin);
1003                 glVertex2f(rect->xmin + zoomx*(cumap->sample[0]-offsx), rect->ymax);
1004                 glEnd();
1005         }*/
1006         /* sample option */
1007         /* XXX 2.48
1008          * if(cumap->flag & CUMA_DRAW_SAMPLE) {
1009                 if(cumap->cur==3) {
1010                         float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
1011                         glColor3ub(240, 240, 240);
1012                         
1013                         glBegin(GL_LINES);
1014                         glVertex2f(rect->xmin + zoomx*(lum-offsx), rect->ymin);
1015                         glVertex2f(rect->xmin + zoomx*(lum-offsx), rect->ymax);
1016                         glEnd();
1017                 }
1018                 else {
1019                         if(cumap->cur==0)
1020                                 glColor3ub(240, 100, 100);
1021                         else if(cumap->cur==1)
1022                                 glColor3ub(100, 240, 100);
1023                         else
1024                                 glColor3ub(100, 100, 240);
1025                         
1026                         glBegin(GL_LINES);
1027                         glVertex2f(rect->xmin + zoomx*(cumap->sample[cumap->cur]-offsx), rect->ymin);
1028                         glVertex2f(rect->xmin + zoomx*(cumap->sample[cumap->cur]-offsx), rect->ymax);
1029                         glEnd();
1030                 }
1031         }*/
1032         
1033         /* the curve */
1034         glColor3ubv((unsigned char*)wcol->item);
1035         glEnable(GL_LINE_SMOOTH);
1036         glEnable(GL_BLEND);
1037         glBegin(GL_LINE_STRIP);
1038         
1039         if(cuma->table==NULL)
1040                 curvemapping_changed(cumap, 0); /* 0 = no remove doubles */
1041         cmp= cuma->table;
1042         
1043         /* first point */
1044         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
1045                 glVertex2f(rect->xmin, rect->ymin + zoomy*(cmp[0].y-offsy));
1046         else {
1047                 fx= rect->xmin + zoomx*(cmp[0].x-offsx + cuma->ext_in[0]);
1048                 fy= rect->ymin + zoomy*(cmp[0].y-offsy + cuma->ext_in[1]);
1049                 glVertex2f(fx, fy);
1050         }
1051         for(a=0; a<=CM_TABLE; a++) {
1052                 fx= rect->xmin + zoomx*(cmp[a].x-offsx);
1053                 fy= rect->ymin + zoomy*(cmp[a].y-offsy);
1054                 glVertex2f(fx, fy);
1055         }
1056         /* last point */
1057         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
1058                 glVertex2f(rect->xmax, rect->ymin + zoomy*(cmp[CM_TABLE].y-offsy));     
1059         else {
1060                 fx= rect->xmin + zoomx*(cmp[CM_TABLE].x-offsx - cuma->ext_out[0]);
1061                 fy= rect->ymin + zoomy*(cmp[CM_TABLE].y-offsy - cuma->ext_out[1]);
1062                 glVertex2f(fx, fy);
1063         }
1064         glEnd();
1065         glDisable(GL_LINE_SMOOTH);
1066         glDisable(GL_BLEND);
1067
1068         /* the points, use aspect to make them visible on edges */
1069         cmp= cuma->curve;
1070         glPointSize(3.0f);
1071         bglBegin(GL_POINTS);
1072         for(a=0; a<cuma->totpoint; a++) {
1073                 if(cmp[a].flag & SELECT)
1074                         UI_ThemeColor(TH_TEXT_HI);
1075                 else
1076                         UI_ThemeColor(TH_TEXT);
1077                 fac[0]= rect->xmin + zoomx*(cmp[a].x-offsx);
1078                 fac[1]= rect->ymin + zoomy*(cmp[a].y-offsy);
1079                 bglVertex2fv(fac);
1080         }
1081         bglEnd();
1082         glPointSize(1.0f);
1083         
1084         /* restore scissortest */
1085         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
1086
1087         /* outline */
1088         glColor3ubv((unsigned char*)wcol->outline);
1089         fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
1090 }
1091
1092
1093 /* ****************************************************** */
1094
1095
1096 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1097 {
1098         glEnable(GL_BLEND);
1099         glShadeModel(GL_SMOOTH);
1100         
1101         /* right quad */
1102         glBegin(GL_POLYGON);
1103         glColor4ub(0, 0, 0, alpha);
1104         glVertex2f(maxx, miny);
1105         glVertex2f(maxx, maxy-0.3*shadsize);
1106         glColor4ub(0, 0, 0, 0);
1107         glVertex2f(maxx+shadsize, maxy-0.75*shadsize);
1108         glVertex2f(maxx+shadsize, miny);
1109         glEnd();
1110         
1111         /* corner shape */
1112         glBegin(GL_POLYGON);
1113         glColor4ub(0, 0, 0, alpha);
1114         glVertex2f(maxx, miny);
1115         glColor4ub(0, 0, 0, 0);
1116         glVertex2f(maxx+shadsize, miny);
1117         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1118         glVertex2f(maxx, miny-shadsize);
1119         glEnd();
1120         
1121         /* bottom quad */               
1122         glBegin(GL_POLYGON);
1123         glColor4ub(0, 0, 0, alpha);
1124         glVertex2f(minx+0.3*shadsize, miny);
1125         glVertex2f(maxx, miny);
1126         glColor4ub(0, 0, 0, 0);
1127         glVertex2f(maxx, miny-shadsize);
1128         glVertex2f(minx+0.5*shadsize, miny-shadsize);
1129         glEnd();
1130         
1131         glDisable(GL_BLEND);
1132         glShadeModel(GL_FLAT);
1133 }
1134
1135 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1136 {
1137         /* accumulated outline boxes to make shade not linear, is more pleasant */
1138         ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20*alpha)>>8);
1139         ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40*alpha)>>8);
1140         ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80*alpha)>>8);
1141         
1142 }
1143
1144
1145 void ui_dropshadow(rctf *rct, float radius, float aspect, int select)
1146 {
1147         float rad;
1148         float a;
1149         char alpha= 2;
1150         
1151         glEnable(GL_BLEND);
1152         
1153         if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
1154                 rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
1155         else
1156                 rad= radius;
1157         
1158         if(select) a= 12.0f*aspect; else a= 12.0f*aspect;
1159         for(; a>0.0f; a-=aspect) {
1160                 /* alpha ranges from 2 to 20 or so */
1161                 glColor4ub(0, 0, 0, alpha);
1162                 alpha+= 2;
1163                 
1164                 gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
1165         }
1166         
1167         /* outline emphasis */
1168         glEnable( GL_LINE_SMOOTH );
1169         glColor4ub(0, 0, 0, 100);
1170         gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius);
1171         glDisable( GL_LINE_SMOOTH );
1172         
1173         glDisable(GL_BLEND);
1174 }
1175