r860: Merge 2.1:
[cinelerra_cv.git] / guicast / bcwindowdraw.C
blobd68a786d868621583c5faba31292faf9d1d57743
1 #include "bcbitmap.h"
2 #include "bcpixmap.h"
3 #include "bcpopup.h"
4 #include "bcresources.h"
5 #include "bcsignals.h"
6 #include "bctimer.h"
7 #include "bcwindowbase.h"
8 #include "clip.h"
9 #include "colors.h"
10 #include "cursors.h"
11 #include "fonts.h"
12 #include "vframe.h"
13 #include <string.h>
15 void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_Pixmap *pixmap)
17         XCopyArea(top_level->display, 
18                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
19                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
20                 top_level->gc, 
21                 x1, 
22                 y1, 
23                 w,
24         h, 
25                 x2, 
26                 y2);
30 void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
32 //if(x == 0) printf("BC_WindowBase::draw_box %d %d %d %d\n", x, y, w, h);
33         XFillRectangle(top_level->display, 
34                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
35                 top_level->gc, 
36                 x, 
37                 y, 
38                 w, 
39                 h);
43 void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
45         XDrawArc(top_level->display, 
46                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
47                 top_level->gc, 
48                 x, 
49                 y, 
50                 (w - 1), 
51                 (h - 2), 
52                 0 * 64, 
53                 360 * 64);
56 void BC_WindowBase::draw_disc(int x, int y, int w, int h, BC_Pixmap *pixmap)
58         XFillArc(top_level->display, 
59                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
60                 top_level->gc, 
61                 x, 
62                 y, 
63                 (w - 1), 
64                 (h - 2), 
65                 0 * 64, 
66                 360 * 64);
69 void BC_WindowBase::clear_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
71         set_color(bg_color);
72         XFillRectangle(top_level->display, 
73                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
74                 top_level->gc, 
75                 x, 
76                 y, 
77                 w, 
78                 h);
81 void BC_WindowBase::draw_text(int x, 
82         int y, 
83         char *text, 
84         int length, 
85         BC_Pixmap *pixmap)
87         if(length < 0) length = strlen(text);
88         int boldface = top_level->current_font & BOLDFACE;
89         int font = top_level->current_font & 0xff;
91         switch(font)
92         {
93                 case MEDIUM_7SEGMENT:
94                         for(int i = 0; i < length; i++)
95                         {
96                                 VFrame *image;
97                                 switch(text[i])
98                                 {
99                                         case '0':
100                                                 image = get_resources()->medium_7segment[0];
101                                                 break;
102                                         case '1':
103                                                 image = get_resources()->medium_7segment[1];
104                                                 break;
105                                         case '2':
106                                                 image = get_resources()->medium_7segment[2];
107                                                 break;
108                                         case '3':
109                                                 image = get_resources()->medium_7segment[3];
110                                                 break;
111                                         case '4':
112                                                 image = get_resources()->medium_7segment[4];
113                                                 break;
114                                         case '5':
115                                                 image = get_resources()->medium_7segment[5];
116                                                 break;
117                                         case '6':
118                                                 image = get_resources()->medium_7segment[6];
119                                                 break;
120                                         case '7':
121                                                 image = get_resources()->medium_7segment[7];
122                                                 break;
123                                         case '8':
124                                                 image = get_resources()->medium_7segment[8];
125                                                 break;
126                                         case '9':
127                                                 image = get_resources()->medium_7segment[9];
128                                                 break;
129                                         case ':':
130                                                 image = get_resources()->medium_7segment[10];
131                                                 break;
132                                         case '.':
133                                                 image = get_resources()->medium_7segment[11];
134                                                 break;
135                                         case 'a':
136                                         case 'A':
137                                                 image = get_resources()->medium_7segment[12];
138                                                 break;
139                                         case 'b':
140                                         case 'B':
141                                                 image = get_resources()->medium_7segment[13];
142                                                 break;
143                                         case 'c':
144                                         case 'C':
145                                                 image = get_resources()->medium_7segment[14];
146                                                 break;
147                                         case 'd':
148                                         case 'D':
149                                                 image = get_resources()->medium_7segment[15];
150                                                 break;
151                                         case 'e':
152                                         case 'E':
153                                                 image = get_resources()->medium_7segment[16];
154                                                 break;
155                                         case 'f':
156                                         case 'F':
157                                                 image = get_resources()->medium_7segment[17];
158                                                 break;
159                                         case ' ':
160                                                 image = get_resources()->medium_7segment[18];
161                                                 break;
162                                         case '-':
163                                                 image = get_resources()->medium_7segment[19];
164                                                 break;
165                                         default:
166                                                 image = get_resources()->medium_7segment[18];
167                                                 break;
168                                 }
170                                 draw_vframe(image, 
171                                         x, 
172                                         y - image->get_h());
173                                 x += image->get_w();
174                         }
175                         break;
177                 default:
178                 {
179 // Set drawing color for dropshadow
180                         int color = get_color();
181                         if(boldface) set_color(BLACK);
184                         for(int k = (boldface ? 1 : 0); k >= 0; k--)
185                         {
186                                 for(int i = 0, j = 0, x2 = x, y2 = y; 
187                                         i <= length; 
188                                         i++)
189                                 {
190                                         if(text[i] == '\n' || text[i] == 0)
191                                         {
192 #ifdef HAVE_XFT
193                                                 if(get_resources()->use_xft && 
194                                                         top_level->get_xft_struct(top_level->current_font))
195                                                 {
196                                                         draw_xft_text(x,
197                                                                 y,
198                                                                 text,
199                                                                 length,
200                                                                 pixmap,
201                                                                 x2,
202                                                                 k,
203                                                                 y2,
204                                                                 j,
205                                                                 i);
206                                                 }
207                                                 else
208 #endif
209                                                 if(get_resources()->use_fontset && top_level->get_curr_fontset())
210                                                 {
211                                                 XmbDrawString(top_level->display, 
212                                                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
213                                                 top_level->get_curr_fontset(),
214                                                 top_level->gc, 
215                                                 x2 + k, 
216                                                 y2 + k, 
217                                                 &text[j], 
218                                                 i - j);
219                                                 }
220                                                 else
221                                                 {
222 //printf("BC_WindowBase::draw_text 3\n");
223                                                         XDrawString(top_level->display, 
224                                                                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
225                                                                 top_level->gc, 
226                                                                 x2 + k, 
227                                                                 y2 + k, 
228                                                                 &text[j], 
229                                                                 i - j);
230                                                 }
234                                                 j = i + 1;
235                                                 y2 += get_text_height(MEDIUMFONT);
236                                         }
237                                 }
238                                 if(boldface) set_color(color);
239                         }
240                         break;
241                 }
242         }
245 void BC_WindowBase::draw_xft_text(int x, 
246         int y, 
247         char *text, 
248         int length, 
249         BC_Pixmap *pixmap,
250         int x2,
251         int k,
252         int y2,
253         int j,
254         int i)
256 #ifdef HAVE_XFT
257 // printf("BC_WindowBase::draw_xft_text_synch 1 %d %p\n", 
258 // get_resources()->use_xft, 
259 // top_level->get_xft_struct(top_level->current_font));
260         XRenderColor color;
261         XftColor xft_color;
262         color.red = (top_level->current_color & 0xff0000) >> 16;
263         color.red |= color.red << 8;
264         color.green = (top_level->current_color & 0xff00) >> 8;
265         color.green |= color.green << 8;
266         color.blue = (top_level->current_color & 0xff);
267         color.blue |= color.blue << 8;
268         color.alpha = 0xffff;
270         XftColorAllocValue(top_level->display,
271                 top_level->vis,
272                 top_level->cmap,
273                 &color,
274                 &xft_color);
276 // printf("BC_WindowBase::draw_text 1 %u   %p %p %p %d %d %s %d\n",
277 // xft_color.pixel,
278 // pixmap ? pixmap->opaque_xft_draw : this->xft_drawable,
279 // &xft_color,
280 // top_level->get_xft_struct(top_level->current_font),
281 // x2 + k, 
282 // y2 + k,
283 // (FcChar8*)&text[j],
284 // i - j);
285         XftDrawString8 (
286                 (XftDraw*)(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw),
287                 &xft_color,
288                 top_level->get_xft_struct(top_level->current_font),
289                 x2 + k, 
290                 y2 + k,
291                 (FcChar8*)&text[j],
292                 i - j);
293         XftColorFree(top_level->display,
294             top_level->vis,
295             top_level->cmap,
296             &xft_color);
297 #endif
301 void BC_WindowBase::draw_center_text(int x, int y, char *text, int length)
303         if(length < 0) length = strlen(text);
304         int w = get_text_width(current_font, text, length);
305         x -= w / 2;
306         draw_text(x, y, text, length);
309 void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
311         XDrawLine(top_level->display, 
312                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
313                 top_level->gc, 
314                 x1, 
315                 y1, 
316                 x2, 
317                 y2);
320 void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
322         int npoints = MIN(x->total, y->total);
323         XPoint *points = new XPoint[npoints];
325         for(int i = 0; i < npoints; i++)
326         {
327                 points[i].x = x->values[i];
328                 points[i].y = y->values[i];
329         }
331         XDrawLines(top_level->display,
332         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
333         top_level->gc,
334         points,
335         npoints,
336         CoordModeOrigin);
338         delete [] points;
342 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
344         XDrawRectangle(top_level->display, 
345                 pixmap->opaque_pixmap, 
346                 top_level->gc, 
347                 x, 
348                 y, 
349                 w - 1, 
350                 h - 1);
353 void BC_WindowBase::draw_3d_border(int x, int y, int w, int h, 
354         int light1, int light2, int shadow1, int shadow2)
356         int lx, ly, ux, uy;
358         h--; w--;
360         lx = x+1;  ly = y+1;
361         ux = x+w-1;  uy = y+h-1;
363         set_color(light1);
364         draw_line(x, y, ux, y);
365         draw_line(x, y, x, uy);
366         set_color(light2);
367         draw_line(lx, ly, ux - 1, ly);
368         draw_line(lx, ly, lx, uy - 1);
370         set_color(shadow1);
371         draw_line(ux, ly, ux, uy);
372         draw_line(lx, uy, ux, uy);
373         set_color(shadow2);
374         draw_line(x + w, y, x + w, y + h);
375         draw_line(x, y + h, x + w, y + h);
378 void BC_WindowBase::draw_3d_box(int x, 
379         int y, 
380         int w, 
381         int h, 
382         int light1, 
383         int light2, 
384         int middle, 
385         int shadow1, 
386         int shadow2,
387         BC_Pixmap *pixmap)
389         int lx, ly, ux, uy;
391         h--; w--;
393         lx = x+1;  ly = y+1;
394         ux = x+w-1;  uy = y+h-1;
396         set_color(middle);
397         draw_box(x, y, w, h, pixmap);
399         set_color(light1);
400         draw_line(x, y, ux, y, pixmap);
401         draw_line(x, y, x, uy, pixmap);
402         set_color(light2);
403         draw_line(lx, ly, ux - 1, ly, pixmap);
404         draw_line(lx, ly, lx, uy - 1, pixmap);
406         set_color(shadow1);
407         draw_line(ux, ly, ux, uy, pixmap);
408         draw_line(lx, uy, ux, uy, pixmap);
409         set_color(shadow2);
410         draw_line(x + w, y, x + w, y + h, pixmap);
411         draw_line(x, y + h, x + w, y + h, pixmap);
414 void BC_WindowBase::draw_colored_box(int x, int y, int w, int h, int down, int highlighted)
416         if(!down)
417         {
418                 if(highlighted)
419                         draw_3d_box(x, y, w, h, 
420                                 top_level->get_resources()->button_light, 
421                                 top_level->get_resources()->button_highlighted, 
422                                 top_level->get_resources()->button_highlighted, 
423                                 top_level->get_resources()->button_shadow,
424                                 BLACK);
425                 else
426                         draw_3d_box(x, y, w, h, 
427                                 top_level->get_resources()->button_light, 
428                                 top_level->get_resources()->button_up, 
429                                 top_level->get_resources()->button_up, 
430                                 top_level->get_resources()->button_shadow,
431                                 BLACK);
432         }
433         else
434         {
435 // need highlighting for toggles
436                 if(highlighted)
437                         draw_3d_box(x, y, w, h, 
438                                 top_level->get_resources()->button_shadow, 
439                                 BLACK, 
440                                 top_level->get_resources()->button_up, 
441                                 top_level->get_resources()->button_up,
442                                 top_level->get_resources()->button_light);
443                 else
444                         draw_3d_box(x, y, w, h, 
445                                 top_level->get_resources()->button_shadow, 
446                                 BLACK, 
447                                 top_level->get_resources()->button_down, 
448                                 top_level->get_resources()->button_down,
449                                 top_level->get_resources()->button_light);
450         }
453 void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
455         int left_indent = 20;
456         int lx, ly, ux, uy;
458         h--; w--;
459         lx = x + 1;  ly = y + 1;
460         ux = x + w - 1;  uy = y + h - 1;
462         set_opaque();
463         if(text && text[0] != 0)
464         {
465                 set_color(BLACK);
466                 set_font(MEDIUMFONT);
467                 draw_text(x + left_indent, y + get_text_height(MEDIUMFONT) / 2, text);
468         }
469         
470         set_color(top_level->get_resources()->button_shadow);
471         draw_line(x, y, x + left_indent - 5, y);
472         draw_line(x, y, x, uy);
473         draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), y, ux, y);
474         draw_line(x, y, x, uy);
475         draw_line(ux, ly, ux, uy);
476         draw_line(lx, uy, ux, uy);
477         set_color(top_level->get_resources()->button_light);
478         draw_line(lx, ly, x + left_indent - 5 - 1, ly);
479         draw_line(lx, ly, lx, uy - 1);
480         draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), ly, ux - 1, ly);
481         draw_line(lx, ly, lx, uy - 1);
482         draw_line(x + w, y, x + w, y + h);
483         draw_line(x, y + h, x + w, y + h);
486 void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
488         int x1, y1, x2, y2, x3, y3;
489         XPoint point[3];
491         x1 = x; x2 = x + w / 2; x3 = x + w - 1;
492         y1 = y; y2 = y + h - 1;
494         point[0].x = x2; point[0].y = y2; point[1].x = x3;
495         point[1].y = y1; point[2].x = x1; point[2].y = y1;
497         XFillPolygon(top_level->display, 
498                 pixmap->opaque_pixmap, 
499                 top_level->gc, 
500                 (XPoint *)point, 
501                 3, 
502                 Nonconvex, 
503                 CoordModeOrigin);
506 void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h, 
507         int light1, int light2, int middle, int shadow1, int shadow2)
509         int x1, y1, x2, y2, x3, y3;
510         XPoint point[3];
512         x1 = x; y1 = y; x2 = x + w / 2;
513         y2 = y + h - 1; x3 = x + w - 1;
515 // middle
516         point[0].x = x2; point[0].y = y1; point[1].x = x3;
517         point[1].y = y2; point[2].x = x1; point[2].y = y2;
519         set_color(middle);
520         XFillPolygon(top_level->display, 
521                 pixmap->opaque_pixmap, 
522                 top_level->gc, 
523                 (XPoint *)point, 
524                 3, 
525                 Nonconvex, 
526                 CoordModeOrigin);
528 // bottom and top right
529         set_color(shadow1);
530         draw_line(x3, y2-1, x1, y2-1);
531         draw_line(x2-1, y1, x3-1, y2);
532         set_color(shadow2);
533         draw_line(x3, y2, x1, y2);
534         draw_line(x2, y1, x3, y2);
536 // top left
537         set_color(light2);
538         draw_line(x2+1, y1, x1+1, y2);
539         set_color(light1);
540         draw_line(x2, y1, x1, y2);
543 void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h, 
544         int light1, int light2, int middle, int shadow1, int shadow2)
546         int x1, y1, x2, y2, x3, y3;
547         XPoint point[3];
549         x1 = x; x2 = x + w / 2; x3 = x + w - 1;
550         y1 = y; y2 = y + h - 1;
552         point[0].x = x2; point[0].y = y2; point[1].x = x3;
553         point[1].y = y1; point[2].x = x1; point[2].y = y1;
555         set_color(middle);
556         XFillPolygon(top_level->display, 
557                 pixmap->opaque_pixmap, 
558                 top_level->gc, 
559                 (XPoint *)point, 
560                 3, 
561                 Nonconvex, 
562                 CoordModeOrigin);
564 // top and bottom left
565         set_color(light2);
566         draw_line(x3-1, y1+1, x1+1, y1+1);
567         draw_line(x1+1, y1, x2+1, y2);
568         set_color(light1);
569         draw_line(x3, y1, x1, y1);
570         draw_line(x1, y1, x2, y2);
572 // bottom right
573         set_color(shadow1);
574         draw_line(x3-1, y1, x2-1, y2);
575         set_color(shadow2);
576         draw_line(x3, y1, x2, y2);
579 void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h, 
580         int light1, int light2, int middle, int shadow1, int shadow2)
582         int x1, y1, x2, y2, x3, y3;
583         XPoint point[3];
585         // draw back arrow
586         y1 = y; x1 = x; y2 = y + h / 2;
587         x2 = x + w - 1; y3 = y + h - 1;
589         point[0].x = x1; point[0].y = y2; point[1].x = x2; 
590         point[1].y = y1; point[2].x = x2; point[2].y = y3;
592         set_color(middle);
593         XFillPolygon(top_level->display, 
594                 pixmap->opaque_pixmap, 
595                 top_level->gc, 
596                 (XPoint *)point, 
597                 3, 
598                 Nonconvex, 
599                 CoordModeOrigin);
601 // right and bottom right
602         set_color(shadow1);
603         draw_line(x2-1, y1, x2-1, y3-1);
604         draw_line(x2, y3-1, x1, y2-1);
605         set_color(shadow2);
606         draw_line(x2, y1, x2, y3);
607         draw_line(x2, y3, x1, y2);
609 // top left
610         set_color(light1);
611         draw_line(x1, y2, x2, y1);
612         set_color(light2);
613         draw_line(x1, y2+1, x2, y1+1);
616 void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h, 
617         int light1, int light2, int middle, int shadow1, int shadow2)
619         int x1, y1, x2, y2, x3, y3;
620         XPoint point[3];
622         y1 = y; y2 = y + h / 2; y3 = y + h - 1; 
623         x1 = x; x2 = x + w - 1;
625         point[0].x = x1; point[0].y = y1; point[1].x = x2; 
626         point[1].y = y2; point[2].x = x1; point[2].y = y3;
628         set_color(middle);
629         XFillPolygon(top_level->display, 
630                 pixmap->opaque_pixmap, 
631                 top_level->gc, 
632                 (XPoint *)point, 
633                 3, 
634                 Nonconvex, 
635                 CoordModeOrigin);
637 // left and top right
638         set_color(light2);
639         draw_line(x1+1, y3, x1+1, y1);
640         draw_line(x1, y1+1, x2, y2+1);
641         set_color(light1);
642         draw_line(x1, y3, x1, y1);
643         draw_line(x1, y1, x2, y2);
645 // bottom right
646         set_color(shadow1);
647         draw_line(x2, y2-1, x1, y3-1);
648         set_color(shadow2);
649         draw_line(x2, y2, x1, y3);
653 void BC_WindowBase::draw_check(int x, int y)
655         const int w = 15, h = 15;
656         draw_line(x + 3, y + h / 2 + 0, x + 6, y + h / 2 + 2);
657         draw_line(x + 3, y + h / 2 + 1, x + 6, y + h / 2 + 3);
658         draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
659         draw_line(x + 3, y + h / 2 + 2, x + 6, y + h / 2 + 4);
660         draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
661         draw_line(x + 6, y + h / 2 + 3, x + w - 4, y + h / 2 - 2);
662         draw_line(x + 6, y + h / 2 + 4, x + w - 4, y + h / 2 - 1);
665 void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
667         if(!tile)
668         {
669                 set_color(bg_color);
670                 draw_box(x, y, w, h);
671         }
672         else
673         {
674                 XSetFillStyle(top_level->display, top_level->gc, FillTiled);
675 // Don't know how slow this is
676                 XSetTile(top_level->display, top_level->gc, tile->get_pixmap());
677                 XSetTSOrigin(top_level->display, top_level->gc, origin_x, origin_y);
678                 draw_box(x, y, w, h);
679                 XSetFillStyle(top_level->display, top_level->gc, FillSolid);
680         }
683 void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
685         Window tempwin;
686         int origin_x, origin_y;
687         XTranslateCoordinates(top_level->display, 
688                         parent_window->win, 
689                         win, 
690                         0, 
691                         0, 
692                         &origin_x, 
693                         &origin_y, 
694                         &tempwin);
696         draw_tiles(parent_window->bg_pixmap, 
697                 origin_x,
698                 origin_y,
699                 x,
700                 y,
701                 w,
702                 h);
705 void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window, 
706         int x, 
707         int y, 
708         int w, 
709         int h, 
710         BC_Pixmap *pixmap)
712         Window tempwin;
713         int top_x, top_y;
715         XTranslateCoordinates(top_level->display, 
716                         win, 
717                         parent_window->win, 
718                         x, 
719                         y, 
720                         &top_x, 
721                         &top_y, 
722                         &tempwin);
724         XCopyArea(top_level->display, 
725                 parent_window->pixmap->opaque_pixmap, 
726                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
727                 top_level->gc, 
728                 top_x, 
729                 top_y, 
730                 w, 
731                 h, 
732                 x, 
733                 y);
736 void BC_WindowBase::draw_background(int x, int y, int w, int h)
738         if(bg_pixmap)
739         {
740                 draw_tiles(bg_pixmap, 0, 0, x, y, w, h);
741         }
742         else
743         {
744                 clear_box(x, y, w, h);
745         }
748 void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap, 
749         int dont_wait,
750         int dest_x, 
751         int dest_y,
752         int dest_w,
753         int dest_h,
754         int src_x,
755         int src_y,
756         int src_w,
757         int src_h,
758         BC_Pixmap *pixmap)
761 // Hide cursor if video enabled
762         update_video_cursor();
764 //printf("BC_WindowBase::draw_bitmap 1\n");
765         if(dest_w <= 0 || dest_h <= 0)
766         {
767 // Use hardware scaling to canvas dimensions if proper color model.
768                 if(bitmap->get_color_model() == BC_YUV420P)
769                 {
770                         dest_w = w;
771                         dest_h = h;
772                 }
773                 else
774                 {
775                         dest_w = bitmap->get_w();
776                         dest_h = bitmap->get_h();
777                 }
778         }
780         if(src_w <= 0 || src_h <= 0)
781         {
782                 src_w = bitmap->get_w();
783                 src_h = bitmap->get_h();
784         }
786         if(video_on)
787         {
788                 bitmap->write_drawable(win, 
789                         top_level->gc, 
790                         src_x, 
791                         src_y, 
792                         src_w,
793                         src_h,
794                         dest_x, 
795                         dest_y, 
796                         dest_w, 
797                         dest_h, 
798                         dont_wait);
799                 top_level->flush();
800         }
801         else
802         {
803                 bitmap->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
804                         top_level->gc, 
805                         dest_x, 
806                         dest_y, 
807                         src_x, 
808                         src_y, 
809                         dest_w, 
810                         dest_h, 
811                         dont_wait);
812         }
813 //printf("BC_WindowBase::draw_bitmap 2\n");
817 void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
819         XDrawPoint(top_level->display, 
820                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
821                 top_level->gc, 
822                 x, 
823                 y);
827 void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap, 
828         int dest_x, 
829         int dest_y,
830         int dest_w,
831         int dest_h,
832         int src_x,
833         int src_y,
834         BC_Pixmap *dst)
836         pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
837                         dest_x, 
838                         dest_y,
839                         dest_w,
840                         dest_h,
841                         src_x,
842                         src_y);
845 void BC_WindowBase::draw_vframe(VFrame *frame, 
846                 int dest_x, 
847                 int dest_y, 
848                 int dest_w, 
849                 int dest_h,
850                 int src_x,
851                 int src_y,
852                 int src_w,
853                 int src_h,
854                 BC_Pixmap *pixmap)
856         if(dest_w <= 0) dest_w = frame->get_w() - src_x;
857         if(dest_h <= 0) dest_h = frame->get_h() - src_y;
858         if(src_w <= 0) src_w = frame->get_w() - src_x;
859         if(src_h <= 0) src_h = frame->get_h() - src_y;
860         CLAMP(src_x, 0, frame->get_w() - 1);
861         CLAMP(src_y, 0, frame->get_h() - 1);
862         if(src_x + src_w > frame->get_w()) src_w = frame->get_w() - src_x;
863         if(src_y + src_h > frame->get_h()) src_h = frame->get_h() - src_y;
865         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(this, 
866                 dest_w, 
867                 dest_h, 
868                 get_color_model(), 
869                 1);
871         temp_bitmap->match_params(dest_w, 
872                 dest_h, 
873                 get_color_model(), 
874                 1);
876         temp_bitmap->read_frame(frame, 
877                 src_x, 
878                 src_y, 
879                 src_w, 
880                 src_h,
881                 0, 
882                 0, 
883                 dest_w, 
884                 dest_h);
886         draw_bitmap(temp_bitmap, 
887                 0, 
888                 dest_x, 
889                 dest_y,
890                 dest_w,
891                 dest_h,
892                 0,
893                 0,
894                 -1,
895                 -1,
896                 pixmap);
899 void BC_WindowBase::draw_tooltip()
901         if(tooltip_popup)
902         {
903                 int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
904                 tooltip_popup->set_color(get_resources()->tooltip_bg_color);
905                 tooltip_popup->draw_box(0, 0, w, h);
906                 tooltip_popup->set_color(BLACK);
907                 tooltip_popup->draw_rectangle(0, 0, w, h);
908                 tooltip_popup->set_font(MEDIUMFONT);
909                 tooltip_popup->draw_text(TOOLTIP_MARGIN, 
910                         get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN, 
911                         tooltip_text);
912         }
915 void BC_WindowBase::slide_left(int distance)
917         if(distance < w)
918         {
919                 XCopyArea(top_level->display, 
920                         pixmap->opaque_pixmap, 
921                         pixmap->opaque_pixmap, 
922                         top_level->gc, 
923                         distance, 
924                         0, 
925                         w - distance, 
926                         h, 
927                         0, 
928                         0);
929         }
932 void BC_WindowBase::slide_right(int distance)
934         if(distance < w)
935         {
936                 XCopyArea(top_level->display, 
937                         pixmap->opaque_pixmap, 
938                         pixmap->opaque_pixmap, 
939                         top_level->gc, 
940                         0, 
941                         0, 
942                         w - distance, 
943                         h, 
944                         distance, 
945                         0);
946         }
949 void BC_WindowBase::slide_up(int distance)
951         if(distance < h)
952         {
953                 XCopyArea(top_level->display, 
954                         pixmap->opaque_pixmap, 
955                         pixmap->opaque_pixmap, 
956                         top_level->gc, 
957                         0, 
958                         distance, 
959                         w, 
960                         h - distance, 
961                         0, 
962                         0);
963                 set_color(bg_color);
964                 XFillRectangle(top_level->display, 
965                         pixmap->opaque_pixmap, 
966                         top_level->gc, 
967                         0, 
968                         h - distance, 
969                         w, 
970                         distance);
971         }
974 void BC_WindowBase::slide_down(int distance)
976         if(distance < h)
977         {
978                 XCopyArea(top_level->display, 
979                         pixmap->opaque_pixmap, 
980                         pixmap->opaque_pixmap, 
981                         top_level->gc, 
982                         0, 
983                         0, 
984                         w, 
985                         h - distance, 
986                         0, 
987                         distance);
988                 set_color(bg_color);
989                 XFillRectangle(top_level->display, 
990                         pixmap->opaque_pixmap, 
991                         top_level->gc, 
992                         0, 
993                         0, 
994                         w, 
995                         distance);
996         }
999 // 3 segments in separate pixmaps.  Obsolete.
1000 void BC_WindowBase::draw_3segment(int x, 
1001         int y, 
1002         int w, 
1003         int h, 
1004         BC_Pixmap *left_image,
1005         BC_Pixmap *mid_image,
1006         BC_Pixmap *right_image,
1007         BC_Pixmap *pixmap)
1009         if(w <= 0 || h <= 0) return;
1010         int left_boundary = left_image->get_w_fixed();
1011         int right_boundary = w - right_image->get_w_fixed();
1012         for(int i = 0; i < w; )
1013         {
1014                 BC_Pixmap *image;
1016                 if(i < left_boundary)
1017                         image = left_image;
1018                 else
1019                 if(i < right_boundary)
1020                         image = mid_image;
1021                 else
1022                         image = right_image;
1024                 int output_w = image->get_w_fixed();
1026                 if(i < left_boundary)
1027                 {
1028                         if(i + output_w > left_boundary) output_w = left_boundary - i;
1029                 }
1030                 else
1031                 if(i < right_boundary)
1032                 {
1033                         if(i + output_w > right_boundary) output_w = right_boundary - i;
1034                 }
1035                 else
1036                         if(i + output_w > w) output_w = w - i;
1038                 image->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap, 
1039                                 x + i, 
1040                                 y,
1041                                 output_w,
1042                                 h,
1043                                 0,
1044                                 0);
1046                 i += output_w;
1047         }
1049 // 3 segments in separate vframes.  Obsolete.
1050 void BC_WindowBase::draw_3segment(int x, 
1051         int y, 
1052         int w, 
1053         int h, 
1054         VFrame *left_image,
1055         VFrame *mid_image,
1056         VFrame *right_image,
1057         BC_Pixmap *pixmap)
1059         if(w <= 0 || h <= 0) return;
1060         int left_boundary = left_image->get_w_fixed();
1061         int right_boundary = w - right_image->get_w_fixed();
1064         for(int i = 0; i < w; )
1065         {
1066                 VFrame *image;
1068                 if(i < left_boundary)
1069                         image = left_image;
1070                 else
1071                 if(i < right_boundary)
1072                         image = mid_image;
1073                 else
1074                         image = right_image;
1075                 
1076                 int output_w = image->get_w_fixed();
1078                 if(i < left_boundary)
1079                 {
1080                         if(i + output_w > left_boundary) output_w = left_boundary - i;
1081                 }
1082                 else
1083                 if(i < right_boundary)
1084                 {
1085                         if(i + output_w > right_boundary) output_w = right_boundary - i;
1086                 }
1087                 else
1088                         if(i + output_w > w) output_w = w - i;
1090                 if(image)
1091                         draw_vframe(image, 
1092                                         x + i, 
1093                                         y,
1094                                         output_w,
1095                                         h,
1096                                         0,
1097                                         0,
1098                                         0,
1099                                         0,
1100                                         pixmap);
1102                 if(output_w == 0) break;
1103                 i += output_w;
1104         }
1107 // Draw all 3 segments in a single vframe for a changing level
1109 // total_x 
1110 // <------>
1111 // total_w
1112 //         <------------------------------------------------------------>
1113 // x
1114 // |
1115 // w           
1116 // <-------------------------------------------------------------------->
1117 // output
1118 //         |-------------------|----------------------|------------------|
1121 void BC_WindowBase::draw_3segmenth(int x, 
1122                 int y, 
1123                 int w, 
1124                 VFrame *image,
1125                 BC_Pixmap *pixmap)
1127         draw_3segmenth(x, 
1128                 y, 
1129                 w, 
1130                 x,
1131                 w,
1132                 image,
1133                 pixmap);
1136 void BC_WindowBase::draw_3segmenth(int x, 
1137                 int y, 
1138                 int w, 
1139                 int total_x,
1140                 int total_w,
1141                 VFrame *image,
1142                 BC_Pixmap *pixmap)
1144         if(total_w <= 0 || w <= 0 || h <= 0) return;
1145         int third_image = image->get_w() / 3;
1146         int half_image = image->get_w() / 2;
1147         int left_boundary = third_image;
1148         int right_boundary = total_w - third_image;
1149         int left_in_x = 0;
1150         int left_in_w = third_image;
1151         int left_out_x = total_x;
1152         int left_out_w = third_image;
1153         int right_in_x = image->get_w() - third_image;
1154         int right_in_w = third_image;
1155         int right_out_x = total_x + total_w - third_image;
1156         int right_out_w = third_image;
1157         int center_out_x = total_x + third_image;
1158         int center_out_w = total_w - third_image * 2;
1159         int image_x, image_w;
1161 //printf("BC_WindowBase::draw_3segment 1 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1162 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1164         if(left_out_x < x)
1165         {
1166                 left_in_w -= x - left_out_x;
1167                 left_out_w -= x - left_out_x;
1168                 left_in_x += x - left_out_x;
1169                 left_out_x += x - left_out_x;
1170         }
1172         if(left_out_x + left_out_w > x + w)
1173         {
1174                 left_in_w -= (left_out_x + left_out_w) - (x + w);
1175                 left_out_w -= (left_out_x + left_out_w) - (x + w);
1176         }
1178         if(right_out_x < x)
1179         {
1180                 right_in_w -= x - right_out_x;
1181                 right_out_w -= x - right_out_x;
1182                 right_in_x += x - right_out_x;
1183                 right_out_x += x - right_out_x;
1184         }
1186         if(right_out_x + right_out_w > x + w)
1187         {
1188                 right_in_w -= (right_out_x + right_out_w) - (x + w);
1189                 right_out_w -= (right_out_x + right_out_w) - (x + w);
1190         }
1192         if(center_out_x < x)
1193         {
1194                 center_out_w -= x - center_out_x;
1195                 center_out_x += x - center_out_x;
1196         }
1198         if(center_out_x + center_out_w > x + w)
1199         {
1200                 center_out_w -= (center_out_x + center_out_w) - (x + w);
1201         }
1203         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level, 
1204                 image->get_w(), 
1205                 image->get_h(), 
1206                 get_color_model(), 
1207                 0);
1208         temp_bitmap->match_params(image->get_w(), 
1209                 image->get_h(), 
1210                 get_color_model(), 
1211                 0);
1212         temp_bitmap->read_frame(image, 
1213                 0, 
1214                 0, 
1215                 image->get_w(), 
1216                 image->get_h());
1219 //printf("BC_WindowBase::draw_3segment 2 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1220 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1221         if(left_out_w > 0)
1222         {
1223                 draw_bitmap(temp_bitmap, 
1224                         0, 
1225                         left_out_x, 
1226                         y,
1227                         left_out_w,
1228                         image->get_h(),
1229                         left_in_x,
1230                         0,
1231                         -1,   // src width and height are meaningless in video_off mode
1232                         -1,
1233                         pixmap);
1234         }
1236         if(right_out_w > 0)
1237         {
1238                 draw_bitmap(temp_bitmap, 
1239                         0, 
1240                         right_out_x, 
1241                         y,
1242                         right_out_w,
1243                         image->get_h(),
1244                         right_in_x,
1245                         0,
1246                         -1,   // src width and height are meaningless in video_off mode
1247                         -1,
1248                         pixmap);
1249         }
1251         for(int pixel = center_out_x; 
1252                 pixel < center_out_x + center_out_w; 
1253                 pixel += half_image)
1254         {
1255                 int fragment_w = half_image;
1256                 if(fragment_w + pixel > center_out_x + center_out_w)
1257                         fragment_w = (center_out_x + center_out_w) - pixel;
1259 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1260                 draw_bitmap(temp_bitmap, 
1261                         0, 
1262                         pixel, 
1263                         y,
1264                         fragment_w,
1265                         image->get_h(),
1266                         third_image,
1267                         0,
1268                         -1,   // src width and height are meaningless in video_off mode
1269                         -1,
1270                         pixmap);
1271         }
1281 void BC_WindowBase::draw_3segmenth(int x, 
1282                 int y, 
1283                 int w, 
1284                 int total_x,
1285                 int total_w,
1286                 BC_Pixmap *src,
1287                 BC_Pixmap *dst)
1289         if(w <= 0 || total_w <= 0) return;
1290         if(!src) printf("BC_WindowBase::draw_3segmenth src=0\n");
1291         int quarter_src = src->get_w() / 4;
1292         int half_src = src->get_w() / 2;
1293         int left_boundary = quarter_src;
1294         int right_boundary = total_w - quarter_src;
1295         int left_in_x = 0;
1296         int left_in_w = quarter_src;
1297         int left_out_x = total_x;
1298         int left_out_w = quarter_src;
1299         int right_in_x = src->get_w() - quarter_src;
1300         int right_in_w = quarter_src;
1301         int right_out_x = total_x + total_w - quarter_src;
1302         int right_out_w = quarter_src;
1303         int center_out_x = total_x + quarter_src;
1304         int center_out_w = total_w - quarter_src * 2;
1305         int src_x, src_w;
1307 //printf("BC_WindowBase::draw_3segment 1 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1308 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1310         if(left_out_x < x)
1311         {
1312                 left_in_w -= x - left_out_x;
1313                 left_out_w -= x - left_out_x;
1314                 left_in_x += x - left_out_x;
1315                 left_out_x += x - left_out_x;
1316         }
1318         if(left_out_x + left_out_w > x + w)
1319         {
1320                 left_in_w -= (left_out_x + left_out_w) - (x + w);
1321                 left_out_w -= (left_out_x + left_out_w) - (x + w);
1322         }
1324         if(right_out_x < x)
1325         {
1326                 right_in_w -= x - right_out_x;
1327                 right_out_w -= x - right_out_x;
1328                 right_in_x += x - right_out_x;
1329                 right_out_x += x - right_out_x;
1330         }
1332         if(right_out_x + right_out_w > x + w)
1333         {
1334                 right_in_w -= (right_out_x + right_out_w) - (x + w);
1335                 right_out_w -= (right_out_x + right_out_w) - (x + w);
1336         }
1338         if(center_out_x < x)
1339         {
1340                 center_out_w -= x - center_out_x;
1341                 center_out_x += x - center_out_x;
1342         }
1344         if(center_out_x + center_out_w > x + w)
1345         {
1346                 center_out_w -= (center_out_x + center_out_w) - (x + w);
1347         }
1350 //printf("BC_WindowBase::draw_3segment 2 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1351 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1352         if(left_out_w > 0)
1353         {
1354                 draw_pixmap(src, 
1355                         left_out_x, 
1356                         y,
1357                         left_out_w,
1358                         src->get_h(),
1359                         left_in_x,
1360                         0,
1361                         dst);
1362         }
1364         if(right_out_w > 0)
1365         {
1366                 draw_pixmap(src, 
1367                         right_out_x, 
1368                         y,
1369                         right_out_w,
1370                         src->get_h(),
1371                         right_in_x,
1372                         0,
1373                         dst);
1374         }
1376         for(int pixel = center_out_x; 
1377                 pixel < center_out_x + center_out_w; 
1378                 pixel += half_src)
1379         {
1380                 int fragment_w = half_src;
1381                 if(fragment_w + pixel > center_out_x + center_out_w)
1382                         fragment_w = (center_out_x + center_out_w) - pixel;
1384 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1385                 draw_pixmap(src, 
1386                         pixel, 
1387                         y,
1388                         fragment_w,
1389                         src->get_h(),
1390                         quarter_src,
1391                         0,
1392                         dst);
1393         }
1398 void BC_WindowBase::draw_3segmenth(int x, 
1399                 int y, 
1400                 int w,
1401                 BC_Pixmap *src,
1402                 BC_Pixmap *dst)
1404         if(w <= 0) return;
1405         int third_image = src->get_w() / 3;
1406         int half_output = w / 2;
1407         int left_boundary = third_image;
1408         int right_boundary = w - third_image;
1409         int left_in_x = 0;
1410         int left_in_w = third_image;
1411         int left_out_x = x;
1412         int left_out_w = third_image;
1413         int right_in_x = src->get_w() - third_image;
1414         int right_in_w = third_image;
1415         int right_out_x = x + w - third_image;
1416         int right_out_w = third_image;
1417         int image_x, image_w;
1419 //printf("BC_WindowBase::draw_3segment 1 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1420 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1422         if(left_out_w > half_output)
1423         {
1424                 left_in_w -= left_out_w - half_output;
1425                 left_out_w -= left_out_w - half_output;
1426         }
1428         if(right_out_x < x + half_output)
1429         {
1430                 right_in_w -= x + half_output - right_out_x;
1431                 right_out_w -= x + half_output - right_out_x;
1432                 right_in_x += x + half_output - right_out_x;
1433                 right_out_x += x + half_output - right_out_x;
1434         }
1436 //printf("BC_WindowBase::draw_3segment 2 left_out_x=%d left_out_w=%d center_out_x=%d center_out_w=%d right_out_x=%d right_out_w=%d\n", 
1437 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1438         if(left_out_w > 0)
1439         {
1440                 draw_pixmap(src, 
1441                         left_out_x, 
1442                         y,
1443                         left_out_w,
1444                         src->get_h(),
1445                         left_in_x,
1446                         0,
1447                         dst);
1448         }
1450         if(right_out_w > 0)
1451         {
1452                 draw_pixmap(src, 
1453                         right_out_x, 
1454                         y,
1455                         right_out_w,
1456                         src->get_h(),
1457                         right_in_x,
1458                         0,
1459                         dst);
1460         }
1462         for(int pixel = left_out_x + left_out_w; 
1463                 pixel < right_out_x; 
1464                 pixel += third_image)
1465         {
1466                 int fragment_w = third_image;
1467                 if(fragment_w + pixel > right_out_x)
1468                         fragment_w = right_out_x - pixel;
1470 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1471                 draw_pixmap(src, 
1472                         pixel, 
1473                         y,
1474                         fragment_w,
1475                         src->get_h(),
1476                         third_image,
1477                         0,
1478                         dst);
1479         }
1489 void BC_WindowBase::draw_3segmentv(int x, 
1490                 int y, 
1491                 int h,
1492                 VFrame *src,
1493                 BC_Pixmap *dst)
1495         if(h <= 0) return;
1496         int third_image = src->get_h() / 3;
1497         int half_output = h / 2;
1498         int left_boundary = third_image;
1499         int right_boundary = h - third_image;
1500         int left_in_y = 0;
1501         int left_in_h = third_image;
1502         int left_out_y = y;
1503         int left_out_h = third_image;
1504         int right_in_y = src->get_h() - third_image;
1505         int right_in_h = third_image;
1506         int right_out_y = y + h - third_image;
1507         int right_out_h = third_image;
1508         int image_y, image_h;
1511         if(left_out_h > half_output)
1512         {
1513                 left_in_h -= left_out_h - half_output;
1514                 left_out_h -= left_out_h - half_output;
1515         }
1517         if(right_out_y < y + half_output)
1518         {
1519                 right_in_h -= y + half_output - right_out_y;
1520                 right_out_h -= y + half_output - right_out_y;
1521                 right_in_y += y + half_output - right_out_y;
1522                 right_out_y += y + half_output - right_out_y;
1523         }
1526         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level, 
1527                 src->get_w(), 
1528                 src->get_h(), 
1529                 get_color_model(), 
1530                 0);
1531         temp_bitmap->match_params(src->get_w(), 
1532                 src->get_h(), 
1533                 get_color_model(), 
1534                 0);
1535         temp_bitmap->read_frame(src, 
1536                 0, 
1537                 0, 
1538                 src->get_w(), 
1539                 src->get_h());
1542         if(left_out_h > 0)
1543         {
1544                 draw_bitmap(temp_bitmap, 
1545                         0,
1546                         x,
1547                         left_out_y, 
1548                         src->get_w(),
1549                         left_out_h,
1550                         0,
1551                         left_in_y,
1552                         -1,
1553                         -1,
1554                         dst);
1555         }
1557         if(right_out_h > 0)
1558         {
1559                 draw_bitmap(temp_bitmap, 
1560                         0,
1561                         x,
1562                         right_out_y, 
1563                         src->get_w(),
1564                         right_out_h,
1565                         0,
1566                         right_in_y,
1567                         -1,
1568                         -1,
1569                         dst);
1570         }
1572         for(int pixel = left_out_y + left_out_h; 
1573                 pixel < right_out_y; 
1574                 pixel += third_image)
1575         {
1576                 int fragment_h = third_image;
1577                 if(fragment_h + pixel > right_out_y)
1578                         fragment_h = right_out_y - pixel;
1580 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1581                 draw_bitmap(temp_bitmap, 
1582                         0,
1583                         x,
1584                         pixel, 
1585                         src->get_w(),
1586                         fragment_h,
1587                         0,
1588                         third_image,
1589                         -1,
1590                         -1,
1591                         dst);
1592         }
1595 void BC_WindowBase::draw_3segmentv(int x, 
1596                 int y, 
1597                 int h,
1598                 BC_Pixmap *src,
1599                 BC_Pixmap *dst)
1601         if(h <= 0) return;
1602         int third_image = src->get_h() / 3;
1603         int half_output = h / 2;
1604         int left_boundary = third_image;
1605         int right_boundary = h - third_image;
1606         int left_in_y = 0;
1607         int left_in_h = third_image;
1608         int left_out_y = y;
1609         int left_out_h = third_image;
1610         int right_in_y = src->get_h() - third_image;
1611         int right_in_h = third_image;
1612         int right_out_y = y + h - third_image;
1613         int right_out_h = third_image;
1614         int image_y, image_h;
1617         if(left_out_h > half_output)
1618         {
1619                 left_in_h -= left_out_h - half_output;
1620                 left_out_h -= left_out_h - half_output;
1621         }
1623         if(right_out_y < y + half_output)
1624         {
1625                 right_in_h -= y + half_output - right_out_y;
1626                 right_out_h -= y + half_output - right_out_y;
1627                 right_in_y += y + half_output - right_out_y;
1628                 right_out_y += y + half_output - right_out_y;
1629         }
1631         if(left_out_h > 0)
1632         {
1633                 draw_pixmap(src, 
1634                         x,
1635                         left_out_y, 
1636                         src->get_w(),
1637                         left_out_h,
1638                         0,
1639                         left_in_y,
1640                         dst);
1641         }
1643         if(right_out_h > 0)
1644         {
1645                 draw_pixmap(src, 
1646                         x,
1647                         right_out_y, 
1648                         src->get_w(),
1649                         right_out_h,
1650                         0,
1651                         right_in_y,
1652                         dst);
1653         }
1655         for(int pixel = left_out_y + left_out_h; 
1656                 pixel < right_out_y; 
1657                 pixel += third_image)
1658         {
1659                 int fragment_h = third_image;
1660                 if(fragment_h + pixel > right_out_y)
1661                         fragment_h = right_out_y - pixel;
1663 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1664                 draw_pixmap(src, 
1665                         x,
1666                         pixel, 
1667                         src->get_w(),
1668                         fragment_h,
1669                         0,
1670                         third_image,
1671                         dst);
1672         }
1676 void BC_WindowBase::draw_9segment(int x, 
1677                 int y, 
1678                 int w,
1679                 int h,
1680                 BC_Pixmap *src,
1681                 BC_Pixmap *dst)
1683         if(w <= 0 || h <= 0) return;
1685         int in_x_third = src->get_w() / 3;
1686         int in_y_third = src->get_h() / 3;
1687         int out_x_half = w / 2;
1688         int out_y_half = h / 2;
1690         int in_x1 = 0;
1691         int in_y1 = 0;
1692         int out_x1 = 0;
1693         int out_y1 = 0;
1694         int in_x2 = MIN(in_x_third, out_x_half);
1695         int in_y2 = MIN(in_y_third, out_y_half);
1696         int out_x2 = in_x2;
1697         int out_y2 = in_y2;
1699         int out_x3 = MAX(w - out_x_half, w - in_x_third);
1700         int out_x4 = w;
1701         int in_x3 = src->get_w() - (out_x4 - out_x3);
1702         int in_x4 = src->get_w();
1704         int out_y3 = MAX(h - out_y_half, h - in_y_third);
1705         int out_y4 = h;
1706         int in_y3 = src->get_h() - (out_y4 - out_y3);
1707         int in_y4 = src->get_h();
1709 // Segment 1
1710         draw_pixmap(src,
1711                 x + out_x1, 
1712                 y + out_y1,
1713                 out_x2 - out_x1,
1714                 out_y2 - out_y1,
1715                 in_x1, 
1716                 in_y1, 
1717                 dst);
1720 // Segment 2 * n
1721         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1722         {
1723                 if(out_x3 - i > 0)
1724                 {
1725                         int w = MIN(in_x3 - in_x2, out_x3 - i);
1726                         draw_pixmap(src,
1727                                 x + i, 
1728                                 y + out_y1,
1729                                 w,
1730                                 out_y2 - out_y1,
1731                                 in_x2, 
1732                                 in_y1, 
1733                                 dst);
1734                 }
1735         }
1741 // Segment 3
1742         draw_pixmap(src,
1743                 x + out_x3, 
1744                 y + out_y1,
1745                 out_x4 - out_x3,
1746                 out_y2 - out_y1,
1747                 in_x3, 
1748                 in_y1, 
1749                 dst);
1753 // Segment 4 * n
1754         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1755         {
1756                 if(out_y3 - i > 0)
1757                 {
1758                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1759                         draw_pixmap(src,
1760                                 x + out_x1, 
1761                                 y + i,
1762                                 out_x2 - out_x1,
1763                                 h,
1764                                 in_x1, 
1765                                 in_y2, 
1766                                 dst);
1767                 }
1768         }
1771 // Segment 5 * n * n
1772         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2 /* in_y_third */)
1773         {
1774                 if(out_y3 - i > 0)
1775                 {
1776                         int h = MIN(in_y3 - in_y2 /* in_y_third */, out_y3 - i);
1779                         for(int j = out_x2; j < out_x3; j += in_x3 - in_x2 /* in_x_third */)
1780                         {
1781                                 int w = MIN(in_x3 - in_x2 /* in_x_third */, out_x3 - j);
1782                                 if(out_x3 - j > 0)
1783                                         draw_pixmap(src,
1784                                                 x + j, 
1785                                                 y + i,
1786                                                 w,
1787                                                 h,
1788                                                 in_x2, 
1789                                                 in_y2, 
1790                                                 dst);
1791                         }
1792                 }
1793         }
1795 // Segment 6 * n
1796         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1797         {
1798                 if(out_y3 - i > 0)
1799                 {
1800                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1801                         draw_pixmap(src,
1802                                 x + out_x3, 
1803                                 y + i,
1804                                 out_x4 - out_x3,
1805                                 h,
1806                                 in_x3, 
1807                                 in_y2, 
1808                                 dst);
1809                 }
1810         }
1815 // Segment 7
1816         draw_pixmap(src,
1817                 x + out_x1, 
1818                 y + out_y3,
1819                 out_x2 - out_x1,
1820                 out_y4 - out_y3,
1821                 in_x1, 
1822                 in_y3, 
1823                 dst);
1826 // Segment 8 * n
1827         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1828         {
1829                 if(out_x3 - i > 0)
1830                 {
1831                         int w = MIN(in_x3 - in_y2, out_x3 - i);
1832                         draw_pixmap(src,
1833                                 x + i, 
1834                                 y + out_y3,
1835                                 w,
1836                                 out_y4 - out_y3,
1837                                 in_x2, 
1838                                 in_y3, 
1839                                 dst);
1840                 }
1841         }
1845 // Segment 9
1846         draw_pixmap(src,
1847                 x + out_x3, 
1848                 y + out_y3,
1849                 out_x4 - out_x3,
1850                 out_y4 - out_y3,
1851                 in_x3, 
1852                 in_y3, 
1853                 dst);
1857 void BC_WindowBase::draw_9segment(int x, 
1858                 int y, 
1859                 int w,
1860                 int h,
1861                 VFrame *src,
1862                 BC_Pixmap *dst)
1864         if(w <= 0 || h <= 0) return;
1866         int in_x_third = src->get_w() / 3;
1867         int in_y_third = src->get_h() / 3;
1868         int out_x_half = w / 2;
1869         int out_y_half = h / 2;
1871         int in_x1 = 0;
1872         int in_y1 = 0;
1873         int out_x1 = 0;
1874         int out_y1 = 0;
1875         int in_x2 = MIN(in_x_third, out_x_half);
1876         int in_y2 = MIN(in_y_third, out_y_half);
1877         int out_x2 = in_x2;
1878         int out_y2 = in_y2;
1880         int out_x3 = MAX(w - out_x_half, w - in_x_third);
1881         int out_x4 = w;
1882         int in_x3 = src->get_w() - (out_x4 - out_x3);
1883         int in_x4 = src->get_w();
1885         int out_y3 = MAX(h - out_y_half, h - in_y_third);
1886         int out_y4 = h;
1887         int in_y3 = src->get_h() - (out_y4 - out_y3);
1888         int in_y4 = src->get_h();
1890 //printf("PFCFrame::draw_9segment 1 %d %d %d %d\n", out_x1, out_x2, out_x3, out_x4);
1891 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_x1, in_x2, in_x3, in_x4);
1892 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_y1, in_y2, in_y3, in_y4);
1894         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level, 
1895                 src->get_w(), 
1896                 src->get_h(), 
1897                 get_color_model(), 
1898                 0);
1899         temp_bitmap->match_params(src->get_w(), 
1900                 src->get_h(), 
1901                 get_color_model(), 
1902                 0);
1903         temp_bitmap->read_frame(src, 
1904                 0, 
1905                 0, 
1906                 src->get_w(), 
1907                 src->get_h());
1909 // Segment 1
1910         draw_bitmap(temp_bitmap,
1911                 0,
1912                 x + out_x1, 
1913                 y + out_y1,
1914                 out_x2 - out_x1,
1915                 out_y2 - out_y1,
1916                 in_x1, 
1917                 in_y1, 
1918                 in_x2 - in_x1,
1919                 in_y2 - in_y1, 
1920                 dst);
1923 // Segment 2 * n
1924         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1925         {
1926                 if(out_x3 - i > 0)
1927                 {
1928                         int w = MIN(in_x3 - in_x2, out_x3 - i);
1929                         draw_bitmap(temp_bitmap,
1930                                 0,
1931                                 x + i, 
1932                                 y + out_y1,
1933                                 w,
1934                                 out_y2 - out_y1,
1935                                 in_x2, 
1936                                 in_y1, 
1937                                 w,
1938                                 in_y2 - in_y1, 
1939                                 dst);
1940                 }
1941         }
1947 // Segment 3
1948         draw_bitmap(temp_bitmap,
1949                 0,
1950                 x + out_x3, 
1951                 y + out_y1,
1952                 out_x4 - out_x3,
1953                 out_y2 - out_y1,
1954                 in_x3, 
1955                 in_y1, 
1956                 in_x4 - in_x3,
1957                 in_y2 - in_y1, 
1958                 dst);
1962 // Segment 4 * n
1963         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1964         {
1965                 if(out_y3 - i > 0)
1966                 {
1967                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1968                         draw_bitmap(temp_bitmap,
1969                                 0,
1970                                 x + out_x1, 
1971                                 y + i,
1972                                 out_x2 - out_x1,
1973                                 h,
1974                                 in_x1, 
1975                                 in_y2, 
1976                                 in_x2 - in_x1,
1977                                 h, 
1978                                 dst);
1979                 }
1980         }
1983 // Segment 5 * n * n
1984         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1985         {
1986                 if(out_y3 - i > 0)
1987                 {
1988                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1991                         for(int j = out_x2; j < out_x3; j += in_x3 - in_x2)
1992                         {
1993                                 int w = MIN(in_x3 - in_x2, out_x3 - j);
1994                                 if(out_x3 - j > 0)
1995                                         draw_bitmap(temp_bitmap,
1996                                                 0,
1997                                                 x + j, 
1998                                                 y + i,
1999                                                 w,
2000                                                 h,
2001                                                 in_x2, 
2002                                                 in_y2, 
2003                                                 w,
2004                                                 h, 
2005                                                 dst);
2006                         }
2007                 }
2008         }
2010 // Segment 6 * n
2011         for(int i = out_y2; i < out_y3; i += in_y_third)
2012         {
2013                 if(out_y3 - i > 0)
2014                 {
2015                         int h = MIN(in_y_third, out_y3 - i);
2016                         draw_bitmap(temp_bitmap,
2017                                 0,
2018                                 x + out_x3, 
2019                                 y + i,
2020                                 out_x4 - out_x3,
2021                                 h,
2022                                 in_x3, 
2023                                 in_y2, 
2024                                 in_x4 - in_x3,
2025                                 h, 
2026                                 dst);
2027                 }
2028         }
2033 // Segment 7
2034         draw_bitmap(temp_bitmap,
2035                 0,
2036                 x + out_x1, 
2037                 y + out_y3,
2038                 out_x2 - out_x1,
2039                 out_y4 - out_y3,
2040                 in_x1, 
2041                 in_y3, 
2042                 in_x2 - in_x1,
2043                 in_y4 - in_y3, 
2044                 dst);
2047 // Segment 8 * n
2048         for(int i = out_x2; i < out_x3; i += in_x_third)
2049         {
2050                 if(out_x3 - i > 0)
2051                 {
2052                         int w = MIN(in_x_third, out_x3 - i);
2053                         draw_bitmap(temp_bitmap,
2054                                 0,
2055                                 x + i, 
2056                                 y + out_y3,
2057                                 w,
2058                                 out_y4 - out_y3,
2059                                 in_x2, 
2060                                 in_y3, 
2061                                 w,
2062                                 in_y4 - in_y3, 
2063                                 dst);
2064                 }
2065         }
2069 // Segment 9
2070         draw_bitmap(temp_bitmap,
2071                 0,
2072                 x + out_x3, 
2073                 y + out_y3,
2074                 out_x4 - out_x3,
2075                 out_y4 - out_y3,
2076                 in_x3, 
2077                 in_y3, 
2078                 in_x4 - in_x3,
2079                 in_y4 - in_y3, 
2080                 dst);