olaf neophyte and de.po updates, valgrind tweaks, delete green lady, inkscape dpi=96
[goodguy/history.git] / cinelerra-5.1 / guicast / bcwindowdraw.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (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
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcbitmap.h"
23 #include "bcpixmap.h"
24 #include "bcpopup.h"
25 #include "bcresources.h"
26 #include "bcsignals.h"
27 #include "bcsynchronous.h"
28 #include "bctimer.h"
29 #include "bcwindowbase.h"
30 #include "clip.h"
31 #include "bccolors.h"
32 #include "bctrace.h"
33 #include "cursors.h"
34 #include "fonts.h"
35 #include "vframe.h"
36 #include <string.h>
37 #include <wchar.h>
38 #include <ft2build.h>
39 #include "workarounds.h"
40
41 void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_Pixmap *pixmap)
42 { BT
43         XCopyArea(top_level->display,
44                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
45                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
46                 top_level->gc, x1, y1, w, h, x2, y2);
47 }
48
49
50 void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
51 { BT
52 //if(x == 0) printf("BC_WindowBase::draw_box %d %d %d %d\n", x, y, w, h);
53         XFillRectangle(top_level->display,
54                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
55                 top_level->gc, x, y, w, h);
56 }
57
58
59 void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
60 { BT
61         XDrawArc(top_level->display,
62                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
63                 top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
64 }
65
66 void BC_WindowBase::draw_arc(int x, int y, int w, int h,
67         int start_angle, int angle_length, BC_Pixmap *pixmap)
68 { BT
69         XDrawArc(top_level->display,
70                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
71                 top_level->gc, x, y, (w - 1), (h - 2), start_angle * 64,
72                 angle_length * 64);
73 }
74
75 void BC_WindowBase::draw_disc(int x, int y, int w, int h, BC_Pixmap *pixmap)
76 { BT
77         XFillArc(top_level->display,
78                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
79                 top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
80 }
81
82 void BC_WindowBase::clear_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
83 { BT
84         set_color(bg_color);
85         Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
86         XFillRectangle(top_level->display, xpixmap, top_level->gc, x, y, w, h);
87 }
88
89 void BC_WindowBase::draw_text_line(int x, int y, const char *text, int len,
90         BC_Pixmap *pixmap)
91 {
92 #ifdef HAVE_XFT
93         if( get_resources()->use_xft ) {
94                 draw_xft_text(x, y, text, len, pixmap);
95                 return;
96         }
97 #endif
98  BT
99         Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
100         if( get_resources()->use_fontset ) {
101                 XFontSet fontset = top_level->get_curr_fontset();
102                 if( fontset ) {
103                         XmbDrawString(top_level->display, xpixmap, fontset,
104                                 top_level->gc, x, y, text, len);
105                         return;
106                 }
107
108         }
109 //printf("BC_WindowBase::draw_text 3\n");
110         XDrawString(top_level->display, xpixmap, top_level->gc, x, y, text, len);
111 }
112
113 void BC_WindowBase::draw_text(int x, int y, const char *text, int length,
114         BC_Pixmap *pixmap)
115 {
116         if( length < 0 ) length = strlen(text);
117         //int boldface = top_level->current_font & BOLDFACE;
118         int font = top_level->current_font & 0xff;
119
120         switch(top_level->current_font) {
121         case MEDIUM_7SEGMENT:
122                 for(int i = 0; i < length; i++) {
123                         VFrame *image, **img7seg = get_resources()->medium_7segment;
124                         int ch = text[i];
125                         switch( ch ) {
126                         case '0': case '1': case '2': case '3': case '4':
127                         case '5': case '6': case '7': case '8': case '9':
128                                   image = img7seg[ch-'0'];  break;
129                         case ':': image = img7seg[10];      break;
130                         case '.': image = img7seg[11];      break;
131                         case 'a': case 'b': case 'c':
132                         case 'd': case 'e': case 'f':  ch -= 'a'-'A';
133                         case 'A': case 'B': case 'C':  /* fallthru */
134                         case 'D': case 'E': case 'F':
135                                 image = img7seg[12+ch-'A']; break;
136                                 break;
137                         case '-': image = img7seg[19];      break;
138                         default:
139                         case ' ': image = img7seg[18];      break;
140                         }
141
142                         draw_vframe(image, x, y - image->get_h());
143                         x += image->get_w();
144                 }
145                 break;
146
147         default: {
148                 if(top_level->get_xft_struct(top_level->current_font)) {
149                         draw_xft_text(x, y, text, length, pixmap);
150                         return;
151                 }
152  BT
153                 for(int i = 0, j = 0; i <= length; i++) {
154                         if(text[i] == '\n' || text[i] == 0) {
155                                 if(get_resources()->use_fontset && top_level->get_curr_fontset()) {
156                                         XmbDrawString(top_level->display,
157                                                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
158                                                 top_level->get_curr_fontset(),
159                                                 top_level->gc, x, y, &text[j], i-j);
160                                 }
161                                 else {
162                                         XDrawString(top_level->display,
163                                                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
164                                                 top_level->gc, x, y, &text[j], i-j);
165                                 }
166                                 j = i + 1;
167                                 y += get_text_height(font);
168                         }
169                 }
170                 break; }
171         }
172 }
173
174 void BC_WindowBase::draw_utf8_text(int x, int y,
175         const char *text, int length, BC_Pixmap *pixmap)
176 {
177         if(length < 0) length = strlen(text);
178
179         if(top_level->get_xft_struct(top_level->current_font))
180         {
181                 draw_xft_text(x,
182                         y,
183                         text,
184                         length,
185                         pixmap,
186                         1);
187                 return;
188         }
189  BT
190         for(int i = 0, j = 0; i <= length; i++)
191         {
192                 if(text[i] == '\n' || text[i] == 0)
193                 {
194                         if(get_resources()->use_fontset && top_level->get_curr_fontset())
195                         {
196                                 XmbDrawString(top_level->display,
197                                         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
198                                         top_level->get_curr_fontset(),
199                                         top_level->gc,
200                                         x,
201                                         y,
202                                         &text[j],
203                                         i - j);
204                         }
205                         else
206                         {
207                                 XDrawString(top_level->display,
208                                         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
209                                         top_level->gc,
210                                         x,
211                                         y,
212                                         &text[j],
213                                         i - j);
214                         }
215
216                         j = i + 1;
217                         y += get_text_height(MEDIUMFONT);
218                 }
219         }
220 }
221
222 void BC_WindowBase::draw_xft_text(int x, int y,
223         const char *text, int length, BC_Pixmap *pixmap, int is_utf8)
224 {
225         int l = length + 1;
226         wchar_t wide_text[l];
227         length = BC_Resources::encode(
228                 is_utf8 ? "UTF8" : BC_Resources::encoding, BC_Resources::wide_encoding,
229                 (char*)text, length, (char*)wide_text, l*sizeof(wchar_t)) / sizeof(wchar_t);
230         draw_xft_text(x, y, wide_text, length, pixmap);
231 }
232
233 void BC_WindowBase::draw_xft_text(int x, int y,
234         const wchar_t *text, int length, BC_Pixmap *pixmap)
235 {
236         int dy = -1;
237         const wchar_t *wsp = text, *wep = wsp + length;
238         int font = top_level->current_font;
239         while( wsp < wep ) {
240                 const wchar_t *wcp = wsp;
241                 while( wcp < wep && *wcp != '\n' ) ++wcp;
242                 int len = wcp - wsp;
243                 if( len > 0 )
244                         draw_single_text(1, font, x, y, wsp, len, pixmap);
245                 if( wcp >= wep ) break;
246                 if( dy < 0 )
247                         dy = get_text_height(font);
248                 y += dy;
249                 wsp = wcp + 1;
250         }
251 }
252
253 void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
254                 int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap)
255 { BT
256         Pixmap draw_pixmap = 0;
257         XftDraw *xft_draw = (XftDraw *)
258                 (pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw);
259         int src_x = x, src_y = y, src_w = 0, src_h = 0;
260         XGCValues values;
261         XGetGCValues(top_level->display, top_level->gc, GCFunction, &values);
262         if( values.function != GXcopy ) {
263                 XSetFunction(top_level->display, top_level->gc, GXcopy);
264                 XGlyphInfo info;
265                 xftTextExtents32(top_level->display, xft_font, fc, len, &info);
266                 src_w = info.width;  src_h = info.height;
267                 draw_pixmap = XCreatePixmap(top_level->display, top_level->win,
268                         src_w, src_h, top_level->default_depth);
269                 int color = get_color(); set_color(0);
270                 XFillRectangle(top_level->display, draw_pixmap, top_level->gc, 0, 0, src_w, src_h);
271                 set_color(color);
272                 xft_draw = xftDrawCreate(top_level->display, draw_pixmap,
273                            top_level->vis, top_level->cmap);
274                 src_x = info.x;  src_y = info.y;
275         }
276         xftDrawString32(xft_draw, xft_color, xft_font, src_x, src_y, fc, len);
277         if( values.function != GXcopy ) {
278                 XSetFunction(top_level->display, top_level->gc, values.function);
279                 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
280                 XCopyArea(top_level->display, draw_pixmap, xpixmap,
281                         top_level->gc, 0, 0, src_w, src_h, x, y);
282                 XFreePixmap(top_level->display, draw_pixmap);
283                 xftDrawDestroy(xft_draw);
284         }
285 }
286
287 int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
288 {
289         return draw_single_text(0, font, 0,0, text, length);
290 }
291
292 int BC_WindowBase::draw_single_text(int draw, int font,
293         int x, int y, const wchar_t *text, int length, BC_Pixmap *pixmap)
294 {
295         if( length < 0 )
296                 length = wcslen(text);
297         if( !length ) return 0;
298
299         if( !get_resources()->use_xft ) {
300  BT
301                 if( !get_font_struct(font) ) return 0;
302                 XChar2b xtext[length], *xp = xtext;
303                 for( int i=0; i<length; ++i,++xp ) {
304                         xp->byte1 = (unsigned char) (text[i] >> 8);
305                         xp->byte2 = (unsigned char) (text[i] & 0xff);
306                 }
307                 if( draw ) {
308                         XDrawString16(top_level->display,
309                                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
310                                 top_level->gc, x, y, xtext, length);
311                 }
312                 return XTextWidth16(get_font_struct(font), xtext, length);
313         }
314
315 #ifdef HAVE_XFT
316         XftColor xft_color;
317         if( draw ) {
318                 XRenderColor color;
319                 color.red = (top_level->current_color & 0xff0000) >> 16;
320                 color.red |= color.red << 8;
321                 color.green = (top_level->current_color & 0xff00) >> 8;
322                 color.green |= color.green << 8;
323                 color.blue = (top_level->current_color & 0xff);
324                 color.blue |= color.blue << 8;
325                 color.alpha = 0xffff;
326
327                 xftColorAllocValue(top_level->display, top_level->vis, top_level->cmap,
328                         &color, &xft_color);
329         }
330
331         int x0 = x;
332         XftFont *basefont = top_level->get_xft_struct(font);
333         XftFont *curfont = 0, *altfont = 0;
334         const wchar_t *up = text, *ubp = up, *uep = ubp + length;
335
336         while( up < uep ) {
337                 XftFont *xft_font = 0;
338                 if( xftCharExists(top_level->display, basefont, *up) )
339                         xft_font = basefont;
340                 else if( altfont ) {
341                         if( xftCharExists(top_level->display, altfont, *up))
342                                 xft_font = altfont;
343                         else {
344                                 xftFontClose(top_level->display, altfont);
345                                 altfont = 0;
346                         }
347                 }
348                 if( !xft_font ) {
349                         FcPattern *pattern = BC_Resources::find_similar_font(*up, basefont->pattern);
350                         if( pattern != 0 ) {
351                                 double psize = 0;
352                                 fcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE, 0, &psize);
353                                 fcPatternAddDouble(pattern, FC_PIXEL_SIZE, psize);
354                                 fcPatternDel(pattern, FC_SCALABLE);
355                                 xft_font = altfont = xftFontOpenPattern(top_level->display, pattern);
356                         }
357                 }
358                 if( !xft_font )
359                         xft_font = basefont;
360                 if( xft_font != curfont ) {
361                         if( curfont && up > ubp ) {
362                                 if( draw ) {
363                                         xft_draw_string(&xft_color, curfont, x, y,
364                                                 (const FcChar32*)ubp, up-ubp, pixmap);
365                                 }
366                                 XGlyphInfo extents;
367                                 xftTextExtents32(top_level->display, curfont,
368                                         (const FcChar32*)ubp, up-ubp, &extents);
369                                 x += extents.xOff;
370                         }
371                         ubp = up;  curfont = xft_font;
372                 }
373                 ++up;
374         }
375
376         if( curfont && up > ubp ) {
377                 if( draw ) {
378                         xft_draw_string(&xft_color, curfont, x, y,
379                                 (const FcChar32*)ubp, up-ubp, pixmap);
380                 }
381                 XGlyphInfo extents;
382                 xftTextExtents32(top_level->display, curfont,
383                         (const FcChar32*)ubp, up-ubp, &extents);
384                 x += extents.xOff;
385         }
386
387         if( altfont )
388                 xftFontClose(top_level->display, altfont);
389
390         xftColorFree(top_level->display, top_level->vis, top_level->cmap, &xft_color);
391 #endif
392         return x - x0;
393 }
394
395 void BC_WindowBase::truncate_text(char *result, const char *text, int w)
396 {
397         int new_w = get_text_width(current_font, text);
398
399         if(new_w > w)
400         {
401                 const char* separator = "...";
402                 int separator_w = get_text_width(current_font, separator);
403 // can't fit
404                 if(separator_w >= w)
405                 {
406                         strcpy(result, separator);
407                         return;
408                 }
409
410                 int text_len = strlen(text);
411 // widen middle gap until it fits
412                 for(int i = text_len / 2; i > 0; i--)
413                 {
414                         strncpy(result, text, i);
415                         result[i] = 0;
416                         strcat(result, separator);
417                         strncat(result, text + text_len - i, i);
418                         result[i + strlen(separator) + i] = 0;
419                         new_w = get_text_width(current_font, result);
420 //printf("BC_WindowBase::truncate_text %d %d %d %s\n", __LINE__, new_w, w, result);
421                         if(new_w < w) return;
422                 }
423
424 // Didn't fit
425                 strcpy(result, separator);
426                 return;
427         }
428         else
429         {
430                 strcpy(result, text);
431         }
432 }
433
434 void BC_WindowBase::draw_center_text(int x, int y, const char *text, int length)
435 {
436         if(length < 0) length = strlen(text);
437         int w = get_text_width(current_font, text, length);
438         x -= w / 2;
439         draw_text(x, y, text, length);
440 }
441
442 void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
443 { BT
444 // Some X drivers can't draw 0 length lines
445         if(x1 == x2 && y1 == y2)
446         {
447                 draw_pixel(x1, y1, pixmap);
448         }
449         else
450         {
451                 XDrawLine(top_level->display,
452                         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
453                         top_level->gc,
454                         x1,
455                         y1,
456                         x2,
457                         y2);
458         }
459 }
460
461 void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
462 { BT
463         int npoints = MIN(x->total, y->total);
464         XPoint *points = new XPoint[npoints];
465
466         for(int i = 0; i < npoints; i++)
467         {
468                 points[i].x = x->values[i];
469                 points[i].y = y->values[i];
470         }
471
472         XDrawLines(top_level->display,
473         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
474         top_level->gc,
475         points,
476         npoints,
477         CoordModeOrigin);
478
479         delete [] points;
480 }
481
482 void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
483 { BT
484         int npoints = MIN(x->total, y->total);
485         XPoint *points = new XPoint[npoints];
486
487         for(int i = 0; i < npoints; i++)
488         {
489                 points[i].x = x->values[i];
490                 points[i].y = y->values[i];
491         }
492
493         XFillPolygon(top_level->display,
494         pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
495         top_level->gc,
496         points,
497         npoints,
498                 Nonconvex,
499         CoordModeOrigin);
500
501         delete [] points;
502 }
503
504
505 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
506 { BT
507         XDrawRectangle(top_level->display,
508                 pixmap->opaque_pixmap,
509                 top_level->gc,
510                 x,
511                 y,
512                 w - 1,
513                 h - 1);
514 }
515
516 void BC_WindowBase::draw_3d_border(int x,
517         int y,
518         int w,
519         int h,
520         int is_down)
521 {
522         draw_3d_border(x,
523                 y,
524                 w,
525                 h,
526                 top_level->get_resources()->border_shadow2,
527                 top_level->get_resources()->border_shadow1,
528                 top_level->get_resources()->border_light1,
529                 top_level->get_resources()->border_light2);
530 }
531
532
533 void BC_WindowBase::draw_3d_border(int x,
534         int y,
535         int w,
536         int h,
537         int light1,
538         int light2,
539         int shadow1,
540         int shadow2)
541 {
542         int lx, ly, ux, uy;
543
544         h--; w--;
545
546         lx = x+1;  ly = y+1;
547         ux = x+w-1;  uy = y+h-1;
548
549         set_color(light1);
550         draw_line(x, y, ux, y);
551         draw_line(x, y, x, uy);
552         set_color(light2);
553         draw_line(lx, ly, ux - 1, ly);
554         draw_line(lx, ly, lx, uy - 1);
555
556         set_color(shadow1);
557         draw_line(ux, ly, ux, uy);
558         draw_line(lx, uy, ux, uy);
559         set_color(shadow2);
560         draw_line(x + w, y, x + w, y + h);
561         draw_line(x, y + h, x + w, y + h);
562 }
563
564 void BC_WindowBase::draw_3d_box(int x,
565         int y,
566         int w,
567         int h,
568         int light1,
569         int light2,
570         int middle,
571         int shadow1,
572         int shadow2,
573         BC_Pixmap *pixmap)
574 {
575         int lx, ly, ux, uy;
576
577         h--; w--;
578
579         lx = x+1;  ly = y+1;
580         ux = x+w-1;  uy = y+h-1;
581
582         set_color(middle);
583         draw_box(x, y, w, h, pixmap);
584
585         set_color(light1);
586         draw_line(x, y, ux, y, pixmap);
587         draw_line(x, y, x, uy, pixmap);
588         set_color(light2);
589         draw_line(lx, ly, ux - 1, ly, pixmap);
590         draw_line(lx, ly, lx, uy - 1, pixmap);
591
592         set_color(shadow1);
593         draw_line(ux, ly, ux, uy, pixmap);
594         draw_line(lx, uy, ux, uy, pixmap);
595         set_color(shadow2);
596         draw_line(x + w, y, x + w, y + h, pixmap);
597         draw_line(x, y + h, x + w, y + h, pixmap);
598 }
599
600 void BC_WindowBase::draw_colored_box(int x, int y, int w, int h, int down, int highlighted)
601 {
602         if(!down)
603         {
604                 if(highlighted)
605                         draw_3d_box(x, y, w, h,
606                                 top_level->get_resources()->button_light,
607                                 top_level->get_resources()->button_highlighted,
608                                 top_level->get_resources()->button_highlighted,
609                                 top_level->get_resources()->button_shadow,
610                                 BLACK);
611                 else
612                         draw_3d_box(x, y, w, h,
613                                 top_level->get_resources()->button_light,
614                                 top_level->get_resources()->button_up,
615                                 top_level->get_resources()->button_up,
616                                 top_level->get_resources()->button_shadow,
617                                 BLACK);
618         }
619         else
620         {
621 // need highlighting for toggles
622                 if(highlighted)
623                         draw_3d_box(x, y, w, h,
624                                 top_level->get_resources()->button_shadow,
625                                 BLACK,
626                                 top_level->get_resources()->button_up,
627                                 top_level->get_resources()->button_up,
628                                 top_level->get_resources()->button_light);
629                 else
630                         draw_3d_box(x, y, w, h,
631                                 top_level->get_resources()->button_shadow,
632                                 BLACK,
633                                 top_level->get_resources()->button_down,
634                                 top_level->get_resources()->button_down,
635                                 top_level->get_resources()->button_light);
636         }
637 }
638
639
640 void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
641 {
642         int left_indent = 20;
643         int lx, ly, ux, uy;
644
645         h--; w--;
646         lx = x + 1;  ly = y + 1;
647         ux = x + w - 1;  uy = y + h - 1;
648
649         set_opaque();
650         if(text && text[0] != 0)
651         {
652                 set_color(BLACK);
653                 set_font(MEDIUMFONT);
654                 draw_text(x + left_indent, y + get_text_height(MEDIUMFONT) / 2, text);
655         }
656
657         set_color(top_level->get_resources()->button_shadow);
658         draw_line(x, y, x + left_indent - 5, y);
659         draw_line(x, y, x, uy);
660         draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), y, ux, y);
661         draw_line(x, y, x, uy);
662         draw_line(ux, ly, ux, uy);
663         draw_line(lx, uy, ux, uy);
664         set_color(top_level->get_resources()->button_light);
665         draw_line(lx, ly, x + left_indent - 5 - 1, ly);
666         draw_line(lx, ly, lx, uy - 1);
667         draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), ly, ux - 1, ly);
668         draw_line(lx, ly, lx, uy - 1);
669         draw_line(x + w, y, x + w, y + h);
670         draw_line(x, y + h, x + w, y + h);
671 }
672
673 void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
674 { BT
675         int x1, y1, x2, y2, x3;
676         XPoint point[3];
677
678         x1 = x; x2 = x + w / 2; x3 = x + w - 1;
679         y1 = y; y2 = y + h - 1;
680
681         point[0].x = x2; point[0].y = y2; point[1].x = x3;
682         point[1].y = y1; point[2].x = x1; point[2].y = y1;
683
684         XFillPolygon(top_level->display,
685                 pixmap->opaque_pixmap,
686                 top_level->gc,
687                 (XPoint *)point,
688                 3,
689                 Nonconvex,
690                 CoordModeOrigin);
691 }
692
693 void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h,
694         int light1, int light2, int middle, int shadow1, int shadow2)
695 { BT
696         int x1, y1, x2, y2, x3;
697         XPoint point[3];
698
699         x1 = x; y1 = y; x2 = x + w / 2;
700         y2 = y + h - 1; x3 = x + w - 1;
701
702 // middle
703         point[0].x = x2; point[0].y = y1; point[1].x = x3;
704         point[1].y = y2; point[2].x = x1; point[2].y = y2;
705
706         set_color(middle);
707         XFillPolygon(top_level->display,
708                 pixmap->opaque_pixmap,
709                 top_level->gc,
710                 (XPoint *)point,
711                 3,
712                 Nonconvex,
713                 CoordModeOrigin);
714
715 // bottom and top right
716         set_color(shadow1);
717         draw_line(x3, y2-1, x1, y2-1);
718         draw_line(x2-1, y1, x3-1, y2);
719         set_color(shadow2);
720         draw_line(x3, y2, x1, y2);
721         draw_line(x2, y1, x3, y2);
722
723 // top left
724         set_color(light2);
725         draw_line(x2+1, y1, x1+1, y2);
726         set_color(light1);
727         draw_line(x2, y1, x1, y2);
728 }
729
730 void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h,
731         int light1, int light2, int middle, int shadow1, int shadow2)
732 {
733         int x1, y1, x2, y2, x3;
734         XPoint point[3];
735
736         x1 = x; x2 = x + w / 2; x3 = x + w - 1;
737         y1 = y; y2 = y + h - 1;
738
739         point[0].x = x2; point[0].y = y2; point[1].x = x3;
740         point[1].y = y1; point[2].x = x1; point[2].y = y1;
741
742         set_color(middle);
743         XFillPolygon(top_level->display,
744                 pixmap->opaque_pixmap,
745                 top_level->gc,
746                 (XPoint *)point,
747                 3,
748                 Nonconvex,
749                 CoordModeOrigin);
750
751 // top and bottom left
752         set_color(light2);
753         draw_line(x3-1, y1+1, x1+1, y1+1);
754         draw_line(x1+1, y1, x2+1, y2);
755         set_color(light1);
756         draw_line(x3, y1, x1, y1);
757         draw_line(x1, y1, x2, y2);
758
759 // bottom right
760         set_color(shadow1);
761         draw_line(x3-1, y1, x2-1, y2);
762         set_color(shadow2);
763         draw_line(x3, y1, x2, y2);
764 }
765
766 void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
767         int light1, int light2, int middle, int shadow1, int shadow2)
768 { BT
769         int x1, y1, x2, y2, y3;
770         XPoint point[3];
771
772         // draw back arrow
773         y1 = y; x1 = x; y2 = y + h / 2;
774         x2 = x + w - 1; y3 = y + h - 1;
775
776         point[0].x = x1; point[0].y = y2; point[1].x = x2;
777         point[1].y = y1; point[2].x = x2; point[2].y = y3;
778
779         set_color(middle);
780         XFillPolygon(top_level->display,
781                 pixmap->opaque_pixmap,
782                 top_level->gc,
783                 (XPoint *)point,
784                 3,
785                 Nonconvex,
786                 CoordModeOrigin);
787
788 // right and bottom right
789         set_color(shadow1);
790         draw_line(x2-1, y1, x2-1, y3-1);
791         draw_line(x2, y3-1, x1, y2-1);
792         set_color(shadow2);
793         draw_line(x2, y1, x2, y3);
794         draw_line(x2, y3, x1, y2);
795
796 // top left
797         set_color(light1);
798         draw_line(x1, y2, x2, y1);
799         set_color(light2);
800         draw_line(x1, y2+1, x2, y1+1);
801 }
802
803 void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h,
804         int light1, int light2, int middle, int shadow1, int shadow2)
805 { BT
806         int x1, y1, x2, y2, y3;
807         XPoint point[3];
808
809         y1 = y; y2 = y + h / 2; y3 = y + h - 1;
810         x1 = x; x2 = x + w - 1;
811
812         point[0].x = x1; point[0].y = y1; point[1].x = x2;
813         point[1].y = y2; point[2].x = x1; point[2].y = y3;
814
815         set_color(middle);
816         XFillPolygon(top_level->display,
817                 pixmap->opaque_pixmap,
818                 top_level->gc,
819                 (XPoint *)point,
820                 3,
821                 Nonconvex,
822                 CoordModeOrigin);
823
824 // left and top right
825         set_color(light2);
826         draw_line(x1+1, y3, x1+1, y1);
827         draw_line(x1, y1+1, x2, y2+1);
828         set_color(light1);
829         draw_line(x1, y3, x1, y1);
830         draw_line(x1, y1, x2, y2);
831
832 // bottom right
833         set_color(shadow1);
834         draw_line(x2, y2-1, x1, y3-1);
835         set_color(shadow2);
836         draw_line(x2, y2, x1, y3);
837 }
838
839
840 void BC_WindowBase::draw_check(int x, int y)
841 {
842         const int w = 15, h = 15;
843         draw_line(x + 3, y + h / 2 + 0, x + 6, y + h / 2 + 2);
844         draw_line(x + 3, y + h / 2 + 1, x + 6, y + h / 2 + 3);
845         draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
846         draw_line(x + 3, y + h / 2 + 2, x + 6, y + h / 2 + 4);
847         draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
848         draw_line(x + 6, y + h / 2 + 3, x + w - 4, y + h / 2 - 2);
849         draw_line(x + 6, y + h / 2 + 4, x + w - 4, y + h / 2 - 1);
850 }
851
852 void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
853 { BT
854         if(!tile)
855         {
856                 set_color(bg_color);
857                 draw_box(x, y, w, h);
858         }
859         else
860         {
861                 XSetFillStyle(top_level->display, top_level->gc, FillTiled);
862 // Don't know how slow this is
863                 XSetTile(top_level->display, top_level->gc, tile->get_pixmap());
864                 XSetTSOrigin(top_level->display, top_level->gc, origin_x, origin_y);
865                 draw_box(x, y, w, h);
866                 XSetFillStyle(top_level->display, top_level->gc, FillSolid);
867         }
868 }
869
870 void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
871 { BT
872         Window tempwin;
873         int origin_x, origin_y;
874         XTranslateCoordinates(top_level->display,
875                         parent_window->win,
876                         win,
877                         0,
878                         0,
879                         &origin_x,
880                         &origin_y,
881                         &tempwin);
882
883         draw_tiles(parent_window->bg_pixmap,
884                 origin_x,
885                 origin_y,
886                 x,
887                 y,
888                 w,
889                 h);
890 }
891
892 void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window,
893         int x,
894         int y,
895         int w,
896         int h,
897         BC_Pixmap *pixmap)
898 { BT
899         Window tempwin;
900         int top_x, top_y;
901         XLockDisplay(top_level->display);
902
903         XTranslateCoordinates(top_level->display,
904                         win,
905                         parent_window->win,
906                         x,
907                         y,
908                         &top_x,
909                         &top_y,
910                         &tempwin);
911
912         XCopyArea(top_level->display,
913                 parent_window->pixmap->opaque_pixmap,
914                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
915                 top_level->gc,
916                 top_x,
917                 top_y,
918                 w,
919                 h,
920                 x,
921                 y);
922
923         XUnlockDisplay(top_level->display);
924 }
925
926 void BC_WindowBase::draw_background(int x, int y, int w, int h)
927 {
928         if(bg_pixmap)
929         {
930                 draw_tiles(bg_pixmap, 0, 0, x, y, w, h);
931         }
932         else
933         {
934                 clear_box(x, y, w, h);
935         }
936 }
937
938 void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap,
939         int dont_wait,
940         int dest_x,
941         int dest_y,
942         int dest_w,
943         int dest_h,
944         int src_x,
945         int src_y,
946         int src_w,
947         int src_h,
948         BC_Pixmap *pixmap)
949 { BT
950 // Hide cursor if video enabled
951         update_video_cursor();
952
953 //printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y);
954         if(dest_w <= 0 || dest_h <= 0)
955         {
956 // Use hardware scaling to canvas dimensions if proper color model.
957                 if(bitmap->get_color_model() == BC_YUV420P)
958                 {
959                         dest_w = w;
960                         dest_h = h;
961                 }
962                 else
963                 {
964                         dest_w = bitmap->get_w();
965                         dest_h = bitmap->get_h();
966                 }
967         }
968
969         if(src_w <= 0 || src_h <= 0)
970         {
971                 src_w = bitmap->get_w();
972                 src_h = bitmap->get_h();
973         }
974
975         if(video_on)
976         {
977                 bitmap->write_drawable(win,
978                         top_level->gc,
979                         src_x,
980                         src_y,
981                         src_w,
982                         src_h,
983                         dest_x,
984                         dest_y,
985                         dest_w,
986                         dest_h,
987                         dont_wait);
988                 top_level->flush();
989         }
990         else
991         {
992                 bitmap->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
993                         top_level->gc,
994                         dest_x,
995                         dest_y,
996                         src_x,
997                         src_y,
998                         dest_w,
999                         dest_h,
1000                         dont_wait);
1001         }
1002 //printf("BC_WindowBase::draw_bitmap 2\n");
1003 }
1004
1005
1006 void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
1007 { BT
1008         XDrawPoint(top_level->display,
1009                 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1010                 top_level->gc,
1011                 x,
1012                 y);
1013 }
1014
1015
1016 void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap,
1017         int dest_x,
1018         int dest_y,
1019         int dest_w,
1020         int dest_h,
1021         int src_x,
1022         int src_y,
1023         BC_Pixmap *dst)
1024 { BT
1025         pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
1026                         dest_x,
1027                         dest_y,
1028                         dest_w,
1029                         dest_h,
1030                         src_x,
1031                         src_y);
1032 }
1033
1034 void BC_WindowBase::draw_vframe(VFrame *frame,
1035                 int dest_x,
1036                 int dest_y,
1037                 int dest_w,
1038                 int dest_h,
1039                 int src_x,
1040                 int src_y,
1041                 int src_w,
1042                 int src_h,
1043                 BC_Pixmap *pixmap)
1044 {
1045         if(dest_w <= 0) dest_w = frame->get_w() - src_x;
1046         if(dest_h <= 0) dest_h = frame->get_h() - src_y;
1047         if(src_w <= 0) src_w = frame->get_w() - src_x;
1048         if(src_h <= 0) src_h = frame->get_h() - src_y;
1049         CLAMP(src_x, 0, frame->get_w() - 1);
1050         CLAMP(src_y, 0, frame->get_h() - 1);
1051         if(src_x + src_w > frame->get_w()) src_w = frame->get_w() - src_x;
1052         if(src_y + src_h > frame->get_h()) src_h = frame->get_h() - src_y;
1053
1054         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(this,
1055                 dest_w,
1056                 dest_h,
1057                 get_color_model(),
1058                 0);
1059
1060         temp_bitmap->match_params(dest_w,
1061                 dest_h,
1062                 get_color_model(),
1063                 0);
1064
1065         temp_bitmap->read_frame(frame,
1066                 src_x,
1067                 src_y,
1068                 src_w,
1069                 src_h,
1070                 0,
1071                 0,
1072                 dest_w,
1073                 dest_h);
1074
1075         draw_bitmap(temp_bitmap,
1076                 0,
1077                 dest_x,
1078                 dest_y,
1079                 dest_w,
1080                 dest_h,
1081                 0,
1082                 0,
1083                 -1,
1084                 -1,
1085                 pixmap);
1086 }
1087
1088 void BC_WindowBase::draw_tooltip(const char *text)
1089 {
1090         if( !text )
1091                 text = tooltip_text;
1092         if(tooltip_popup && text)
1093         {
1094                 int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
1095                 tooltip_popup->set_color(get_resources()->tooltip_bg_color);
1096                 tooltip_popup->draw_box(0, 0, w, h);
1097                 tooltip_popup->set_color(BLACK);
1098                 tooltip_popup->draw_rectangle(0, 0, w, h);
1099                 tooltip_popup->set_font(MEDIUMFONT);
1100                 tooltip_popup->draw_text(TOOLTIP_MARGIN,
1101                         get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN,
1102                         text);
1103         }
1104 }
1105
1106 void BC_WindowBase::slide_left(int distance)
1107 { BT
1108         if(distance < w)
1109         {
1110                 XCopyArea(top_level->display,
1111                         pixmap->opaque_pixmap,
1112                         pixmap->opaque_pixmap,
1113                         top_level->gc,
1114                         distance,
1115                         0,
1116                         w - distance,
1117                         h,
1118                         0,
1119                         0);
1120         }
1121 }
1122
1123 void BC_WindowBase::slide_right(int distance)
1124 { BT
1125         if(distance < w)
1126         {
1127                 XCopyArea(top_level->display,
1128                         pixmap->opaque_pixmap,
1129                         pixmap->opaque_pixmap,
1130                         top_level->gc,
1131                         0,
1132                         0,
1133                         w - distance,
1134                         h,
1135                         distance,
1136                         0);
1137         }
1138 }
1139
1140 void BC_WindowBase::slide_up(int distance)
1141 { BT
1142         if(distance < h)
1143         {
1144                 XCopyArea(top_level->display,
1145                         pixmap->opaque_pixmap,
1146                         pixmap->opaque_pixmap,
1147                         top_level->gc,
1148                         0,
1149                         distance,
1150                         w,
1151                         h - distance,
1152                         0,
1153                         0);
1154                 set_color(bg_color);
1155                 XFillRectangle(top_level->display,
1156                         pixmap->opaque_pixmap,
1157                         top_level->gc,
1158                         0,
1159                         h - distance,
1160                         w,
1161                         distance);
1162         }
1163 }
1164
1165 void BC_WindowBase::slide_down(int distance)
1166 { BT
1167         if(distance < h)
1168         {
1169                 XCopyArea(top_level->display,
1170                         pixmap->opaque_pixmap,
1171                         pixmap->opaque_pixmap,
1172                         top_level->gc,
1173                         0,
1174                         0,
1175                         w,
1176                         h - distance,
1177                         0,
1178                         distance);
1179                 set_color(bg_color);
1180                 XFillRectangle(top_level->display,
1181                         pixmap->opaque_pixmap,
1182                         top_level->gc,
1183                         0,
1184                         0,
1185                         w,
1186                         distance);
1187         }
1188 }
1189
1190 // 3 segments in separate pixmaps.  Obsolete.
1191 void BC_WindowBase::draw_3segment(int x,
1192         int y,
1193         int w,
1194         int h,
1195         BC_Pixmap *left_image,
1196         BC_Pixmap *mid_image,
1197         BC_Pixmap *right_image,
1198         BC_Pixmap *pixmap)
1199 {
1200         if(w <= 0 || h <= 0) return;
1201         int left_boundary = left_image->get_w_fixed();
1202         int right_boundary = w - right_image->get_w_fixed();
1203         for(int i = 0; i < w; )
1204         {
1205                 BC_Pixmap *image;
1206
1207                 if(i < left_boundary)
1208                         image = left_image;
1209                 else
1210                 if(i < right_boundary)
1211                         image = mid_image;
1212                 else
1213                         image = right_image;
1214
1215                 int output_w = image->get_w_fixed();
1216
1217                 if(i < left_boundary)
1218                 {
1219                         if(i + output_w > left_boundary) output_w = left_boundary - i;
1220                 }
1221                 else
1222                 if(i < right_boundary)
1223                 {
1224                         if(i + output_w > right_boundary) output_w = right_boundary - i;
1225                 }
1226                 else
1227                         if(i + output_w > w) output_w = w - i;
1228
1229                 image->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1230                                 x + i,
1231                                 y,
1232                                 output_w,
1233                                 h,
1234                                 0,
1235                                 0);
1236
1237                 i += output_w;
1238         }
1239 }
1240 // 3 segments in separate vframes.  Obsolete.
1241 void BC_WindowBase::draw_3segment(int x,
1242         int y,
1243         int w,
1244         int h,
1245         VFrame *left_image,
1246         VFrame *mid_image,
1247         VFrame *right_image,
1248         BC_Pixmap *pixmap)
1249 {
1250         if(w <= 0 || h <= 0) return;
1251         int left_boundary = left_image->get_w_fixed();
1252         int right_boundary = w - right_image->get_w_fixed();
1253
1254
1255         for(int i = 0; i < w; )
1256         {
1257                 VFrame *image;
1258
1259                 if(i < left_boundary)
1260                         image = left_image;
1261                 else
1262                 if(i < right_boundary)
1263                         image = mid_image;
1264                 else
1265                         image = right_image;
1266
1267                 int output_w = image->get_w_fixed();
1268
1269                 if(i < left_boundary)
1270                 {
1271                         if(i + output_w > left_boundary) output_w = left_boundary - i;
1272                 }
1273                 else
1274                 if(i < right_boundary)
1275                 {
1276                         if(i + output_w > right_boundary) output_w = right_boundary - i;
1277                 }
1278                 else
1279                         if(i + output_w > w) output_w = w - i;
1280
1281                 if(image)
1282                         draw_vframe(image,
1283                                         x + i,
1284                                         y,
1285                                         output_w,
1286                                         h,
1287                                         0,
1288                                         0,
1289                                         0,
1290                                         0,
1291                                         pixmap);
1292
1293                 if(output_w == 0) break;
1294                 i += output_w;
1295         }
1296 }
1297
1298 // Draw all 3 segments in a single vframe for a changing level
1299
1300 // total_x
1301 // <------>
1302 // total_w
1303 //         <------------------------------------------------------------>
1304 // x
1305 // |
1306 // w
1307 // <-------------------------------------------------------------------->
1308 // output
1309 //         |-------------------|----------------------|------------------|
1310
1311
1312 void BC_WindowBase::draw_3segmenth(int x,
1313                 int y,
1314                 int w,
1315                 VFrame *image,
1316                 BC_Pixmap *pixmap)
1317 {
1318         draw_3segmenth(x,
1319                 y,
1320                 w,
1321                 x,
1322                 w,
1323                 image,
1324                 pixmap);
1325 }
1326
1327 void BC_WindowBase::draw_3segmenth(int x,
1328                 int y,
1329                 int w,
1330                 int total_x,
1331                 int total_w,
1332                 VFrame *image,
1333                 BC_Pixmap *pixmap)
1334 {
1335         if(total_w <= 0 || w <= 0 || h <= 0) return;
1336         int third_image = image->get_w() / 3;
1337         int half_image = image->get_w() / 2;
1338         //int left_boundary = third_image;
1339         //int right_boundary = total_w - third_image;
1340         int left_in_x = 0;
1341         int left_in_w = third_image;
1342         int left_out_x = total_x;
1343         int left_out_w = third_image;
1344         int right_in_x = image->get_w() - third_image;
1345         int right_in_w = third_image;
1346         int right_out_x = total_x + total_w - third_image;
1347         int right_out_w = third_image;
1348         int center_out_x = total_x + third_image;
1349         int center_out_w = total_w - third_image * 2;
1350         //int image_x, image_w;
1351
1352 //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",
1353 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1354
1355         if(left_out_x < x)
1356         {
1357                 left_in_w -= x - left_out_x;
1358                 left_out_w -= x - left_out_x;
1359                 left_in_x += x - left_out_x;
1360                 left_out_x += x - left_out_x;
1361         }
1362
1363         if(left_out_x + left_out_w > x + w)
1364         {
1365                 left_in_w -= (left_out_x + left_out_w) - (x + w);
1366                 left_out_w -= (left_out_x + left_out_w) - (x + w);
1367         }
1368
1369         if(right_out_x < x)
1370         {
1371                 right_in_w -= x - right_out_x;
1372                 right_out_w -= x - right_out_x;
1373                 right_in_x += x - right_out_x;
1374                 right_out_x += x - right_out_x;
1375         }
1376
1377         if(right_out_x + right_out_w > x + w)
1378         {
1379                 right_in_w -= (right_out_x + right_out_w) - (x + w);
1380                 right_out_w -= (right_out_x + right_out_w) - (x + w);
1381         }
1382
1383         if(center_out_x < x)
1384         {
1385                 center_out_w -= x - center_out_x;
1386                 center_out_x += x - center_out_x;
1387         }
1388
1389         if(center_out_x + center_out_w > x + w)
1390         {
1391                 center_out_w -= (center_out_x + center_out_w) - (x + w);
1392         }
1393
1394         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1395                 image->get_w(),
1396                 image->get_h(),
1397                 get_color_model(),
1398                 0);
1399         temp_bitmap->match_params(image->get_w(),
1400                 image->get_h(),
1401                 get_color_model(),
1402                 0);
1403         temp_bitmap->read_frame(image,
1404                 0,
1405                 0,
1406                 image->get_w(),
1407                 image->get_h());
1408
1409
1410 //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",
1411 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1412         if(left_out_w > 0)
1413         {
1414                 draw_bitmap(temp_bitmap,
1415                         0,
1416                         left_out_x,
1417                         y,
1418                         left_out_w,
1419                         image->get_h(),
1420                         left_in_x,
1421                         0,
1422                         -1,   // src width and height are meaningless in video_off mode
1423                         -1,
1424                         pixmap);
1425         }
1426
1427         if(right_out_w > 0)
1428         {
1429                 draw_bitmap(temp_bitmap,
1430                         0,
1431                         right_out_x,
1432                         y,
1433                         right_out_w,
1434                         image->get_h(),
1435                         right_in_x,
1436                         0,
1437                         -1,   // src width and height are meaningless in video_off mode
1438                         -1,
1439                         pixmap);
1440         }
1441
1442         for(int pixel = center_out_x;
1443                 pixel < center_out_x + center_out_w;
1444                 pixel += half_image)
1445         {
1446                 int fragment_w = half_image;
1447                 if(fragment_w + pixel > center_out_x + center_out_w)
1448                         fragment_w = (center_out_x + center_out_w) - pixel;
1449
1450 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1451                 draw_bitmap(temp_bitmap,
1452                         0,
1453                         pixel,
1454                         y,
1455                         fragment_w,
1456                         image->get_h(),
1457                         third_image,
1458                         0,
1459                         -1,   // src width and height are meaningless in video_off mode
1460                         -1,
1461                         pixmap);
1462         }
1463
1464 }
1465
1466
1467
1468
1469
1470
1471
1472 void BC_WindowBase::draw_3segmenth(int x,
1473                 int y,
1474                 int w,
1475                 int total_x,
1476                 int total_w,
1477                 BC_Pixmap *src,
1478                 BC_Pixmap *dst)
1479 {
1480         if(w <= 0 || total_w <= 0) return;
1481         if(!src) printf("BC_WindowBase::draw_3segmenth src=0\n");
1482         int quarter_src = src->get_w() / 4;
1483         int half_src = src->get_w() / 2;
1484         //int left_boundary = quarter_src;
1485         //int right_boundary = total_w - quarter_src;
1486         int left_in_x = 0;
1487         int left_in_w = quarter_src;
1488         int left_out_x = total_x;
1489         int left_out_w = quarter_src;
1490         int right_in_x = src->get_w() - quarter_src;
1491         int right_in_w = quarter_src;
1492         int right_out_x = total_x + total_w - quarter_src;
1493         int right_out_w = quarter_src;
1494         int center_out_x = total_x + quarter_src;
1495         int center_out_w = total_w - quarter_src * 2;
1496         //int src_x, src_w;
1497
1498 //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",
1499 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1500
1501         if(left_out_x < x)
1502         {
1503                 left_in_w -= x - left_out_x;
1504                 left_out_w -= x - left_out_x;
1505                 left_in_x += x - left_out_x;
1506                 left_out_x += x - left_out_x;
1507         }
1508
1509         if(left_out_x + left_out_w > x + w)
1510         {
1511                 left_in_w -= (left_out_x + left_out_w) - (x + w);
1512                 left_out_w -= (left_out_x + left_out_w) - (x + w);
1513         }
1514
1515         if(right_out_x < x)
1516         {
1517                 right_in_w -= x - right_out_x;
1518                 right_out_w -= x - right_out_x;
1519                 right_in_x += x - right_out_x;
1520                 right_out_x += x - right_out_x;
1521         }
1522
1523         if(right_out_x + right_out_w > x + w)
1524         {
1525                 right_in_w -= (right_out_x + right_out_w) - (x + w);
1526                 right_out_w -= (right_out_x + right_out_w) - (x + w);
1527         }
1528
1529         if(center_out_x < x)
1530         {
1531                 center_out_w -= x - center_out_x;
1532                 center_out_x += x - center_out_x;
1533         }
1534
1535         if(center_out_x + center_out_w > x + w)
1536         {
1537                 center_out_w -= (center_out_x + center_out_w) - (x + w);
1538         }
1539
1540
1541 //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",
1542 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1543         if(left_out_w > 0)
1544         {
1545                 draw_pixmap(src,
1546                         left_out_x,
1547                         y,
1548                         left_out_w,
1549                         src->get_h(),
1550                         left_in_x,
1551                         0,
1552                         dst);
1553         }
1554
1555         if(right_out_w > 0)
1556         {
1557                 draw_pixmap(src,
1558                         right_out_x,
1559                         y,
1560                         right_out_w,
1561                         src->get_h(),
1562                         right_in_x,
1563                         0,
1564                         dst);
1565         }
1566
1567         for(int pixel = center_out_x;
1568                 pixel < center_out_x + center_out_w;
1569                 pixel += half_src)
1570         {
1571                 int fragment_w = half_src;
1572                 if(fragment_w + pixel > center_out_x + center_out_w)
1573                         fragment_w = (center_out_x + center_out_w) - pixel;
1574
1575 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1576                 draw_pixmap(src,
1577                         pixel,
1578                         y,
1579                         fragment_w,
1580                         src->get_h(),
1581                         quarter_src,
1582                         0,
1583                         dst);
1584         }
1585
1586 }
1587
1588
1589 void BC_WindowBase::draw_3segmenth(int x,
1590                 int y,
1591                 int w,
1592                 BC_Pixmap *src,
1593                 BC_Pixmap *dst)
1594 {
1595         if(w <= 0) return;
1596         int third_image = src->get_w() / 3;
1597         int half_output = w / 2;
1598         //int left_boundary = third_image;
1599         //int right_boundary = w - third_image;
1600         int left_in_x = 0;
1601         int left_in_w = third_image;
1602         int left_out_x = x;
1603         int left_out_w = third_image;
1604         int right_in_x = src->get_w() - third_image;
1605         int right_in_w = third_image;
1606         int right_out_x = x + w - third_image;
1607         int right_out_w = third_image;
1608         //int image_x, image_w;
1609
1610 //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",
1611 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1612
1613         if(left_out_w > half_output)
1614         {
1615                 left_in_w -= left_out_w - half_output;
1616                 left_out_w -= left_out_w - half_output;
1617         }
1618
1619         if(right_out_x < x + half_output)
1620         {
1621                 right_in_w -= x + half_output - right_out_x;
1622                 right_out_w -= x + half_output - right_out_x;
1623                 right_in_x += x + half_output - right_out_x;
1624                 right_out_x += x + half_output - right_out_x;
1625         }
1626
1627 //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",
1628 //      left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1629         if(left_out_w > 0)
1630         {
1631                 draw_pixmap(src,
1632                         left_out_x,
1633                         y,
1634                         left_out_w,
1635                         src->get_h(),
1636                         left_in_x,
1637                         0,
1638                         dst);
1639         }
1640
1641         if(right_out_w > 0)
1642         {
1643                 draw_pixmap(src,
1644                         right_out_x,
1645                         y,
1646                         right_out_w,
1647                         src->get_h(),
1648                         right_in_x,
1649                         0,
1650                         dst);
1651         }
1652
1653         for(int pixel = left_out_x + left_out_w;
1654                 pixel < right_out_x;
1655                 pixel += third_image)
1656         {
1657                 int fragment_w = third_image;
1658                 if(fragment_w + pixel > right_out_x)
1659                         fragment_w = right_out_x - pixel;
1660
1661 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1662                 draw_pixmap(src,
1663                         pixel,
1664                         y,
1665                         fragment_w,
1666                         src->get_h(),
1667                         third_image,
1668                         0,
1669                         dst);
1670         }
1671
1672 }
1673
1674
1675
1676
1677
1678
1679
1680 void BC_WindowBase::draw_3segmentv(int x,
1681                 int y,
1682                 int h,
1683                 VFrame *src,
1684                 BC_Pixmap *dst)
1685 {
1686         if(h <= 0) return;
1687         int third_image = src->get_h() / 3;
1688         int half_output = h / 2;
1689         //int left_boundary = third_image;
1690         //int right_boundary = h - third_image;
1691         int left_in_y = 0;
1692         int left_in_h = third_image;
1693         int left_out_y = y;
1694         int left_out_h = third_image;
1695         int right_in_y = src->get_h() - third_image;
1696         int right_in_h = third_image;
1697         int right_out_y = y + h - third_image;
1698         int right_out_h = third_image;
1699         //int image_y, image_h;
1700
1701
1702         if(left_out_h > half_output)
1703         {
1704                 left_in_h -= left_out_h - half_output;
1705                 left_out_h -= left_out_h - half_output;
1706         }
1707
1708         if(right_out_y < y + half_output)
1709         {
1710                 right_in_h -= y + half_output - right_out_y;
1711                 right_out_h -= y + half_output - right_out_y;
1712                 right_in_y += y + half_output - right_out_y;
1713                 right_out_y += y + half_output - right_out_y;
1714         }
1715
1716
1717         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1718                 src->get_w(),
1719                 src->get_h(),
1720                 get_color_model(),
1721                 0);
1722         temp_bitmap->match_params(src->get_w(),
1723                 src->get_h(),
1724                 get_color_model(),
1725                 0);
1726         temp_bitmap->read_frame(src,
1727                 0,
1728                 0,
1729                 src->get_w(),
1730                 src->get_h());
1731
1732
1733         if(left_out_h > 0)
1734         {
1735                 draw_bitmap(temp_bitmap,
1736                         0,
1737                         x,
1738                         left_out_y,
1739                         src->get_w(),
1740                         left_out_h,
1741                         0,
1742                         left_in_y,
1743                         -1,
1744                         -1,
1745                         dst);
1746         }
1747
1748         if(right_out_h > 0)
1749         {
1750                 draw_bitmap(temp_bitmap,
1751                         0,
1752                         x,
1753                         right_out_y,
1754                         src->get_w(),
1755                         right_out_h,
1756                         0,
1757                         right_in_y,
1758                         -1,
1759                         -1,
1760                         dst);
1761         }
1762
1763         for(int pixel = left_out_y + left_out_h;
1764                 pixel < right_out_y;
1765                 pixel += third_image)
1766         {
1767                 int fragment_h = third_image;
1768                 if(fragment_h + pixel > right_out_y)
1769                         fragment_h = right_out_y - pixel;
1770
1771 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1772                 draw_bitmap(temp_bitmap,
1773                         0,
1774                         x,
1775                         pixel,
1776                         src->get_w(),
1777                         fragment_h,
1778                         0,
1779                         third_image,
1780                         -1,
1781                         -1,
1782                         dst);
1783         }
1784 }
1785
1786 void BC_WindowBase::draw_3segmentv(int x,
1787                 int y,
1788                 int h,
1789                 BC_Pixmap *src,
1790                 BC_Pixmap *dst)
1791 {
1792         if(h <= 0) return;
1793         int third_image = src->get_h() / 3;
1794         int half_output = h / 2;
1795         //int left_boundary = third_image;
1796         //int right_boundary = h - third_image;
1797         int left_in_y = 0;
1798         int left_in_h = third_image;
1799         int left_out_y = y;
1800         int left_out_h = third_image;
1801         int right_in_y = src->get_h() - third_image;
1802         int right_in_h = third_image;
1803         int right_out_y = y + h - third_image;
1804         int right_out_h = third_image;
1805         //int image_y, image_h;
1806
1807
1808         if(left_out_h > half_output)
1809         {
1810                 left_in_h -= left_out_h - half_output;
1811                 left_out_h -= left_out_h - half_output;
1812         }
1813
1814         if(right_out_y < y + half_output)
1815         {
1816                 right_in_h -= y + half_output - right_out_y;
1817                 right_out_h -= y + half_output - right_out_y;
1818                 right_in_y += y + half_output - right_out_y;
1819                 right_out_y += y + half_output - right_out_y;
1820         }
1821
1822         if(left_out_h > 0)
1823         {
1824                 draw_pixmap(src,
1825                         x,
1826                         left_out_y,
1827                         src->get_w(),
1828                         left_out_h,
1829                         0,
1830                         left_in_y,
1831                         dst);
1832         }
1833
1834         if(right_out_h > 0)
1835         {
1836                 draw_pixmap(src,
1837                         x,
1838                         right_out_y,
1839                         src->get_w(),
1840                         right_out_h,
1841                         0,
1842                         right_in_y,
1843                         dst);
1844         }
1845
1846         for(int pixel = left_out_y + left_out_h;
1847                 pixel < right_out_y;
1848                 pixel += third_image)
1849         {
1850                 int fragment_h = third_image;
1851                 if(fragment_h + pixel > right_out_y)
1852                         fragment_h = right_out_y - pixel;
1853
1854 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1855                 draw_pixmap(src,
1856                         x,
1857                         pixel,
1858                         src->get_w(),
1859                         fragment_h,
1860                         0,
1861                         third_image,
1862                         dst);
1863         }
1864 }
1865
1866
1867 void BC_WindowBase::draw_9segment(int x,
1868                 int y,
1869                 int w,
1870                 int h,
1871                 BC_Pixmap *src,
1872                 BC_Pixmap *dst)
1873 {
1874         if(w <= 0 || h <= 0) return;
1875
1876         int in_x_third = src->get_w() / 3;
1877         int in_y_third = src->get_h() / 3;
1878         int out_x_half = w / 2;
1879         int out_y_half = h / 2;
1880
1881         int in_x1 = 0;
1882         int in_y1 = 0;
1883         int out_x1 = 0;
1884         int out_y1 = 0;
1885         int in_x2 = MIN(in_x_third, out_x_half);
1886         int in_y2 = MIN(in_y_third, out_y_half);
1887         int out_x2 = in_x2;
1888         int out_y2 = in_y2;
1889
1890         int out_x3 = MAX(w - out_x_half, w - in_x_third);
1891         int out_x4 = w;
1892         int in_x3 = src->get_w() - (out_x4 - out_x3);
1893         //int in_x4 = src->get_w();
1894
1895         int out_y3 = MAX(h - out_y_half, h - in_y_third);
1896         int out_y4 = h;
1897         int in_y3 = src->get_h() - (out_y4 - out_y3);
1898         //int in_y4 = src->get_h();
1899
1900 // Segment 1
1901         draw_pixmap(src,
1902                 x + out_x1,
1903                 y + out_y1,
1904                 out_x2 - out_x1,
1905                 out_y2 - out_y1,
1906                 in_x1,
1907                 in_y1,
1908                 dst);
1909
1910
1911 // Segment 2 * n
1912         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1913         {
1914                 if(out_x3 - i > 0)
1915                 {
1916                         int w = MIN(in_x3 - in_x2, out_x3 - i);
1917                         draw_pixmap(src,
1918                                 x + i,
1919                                 y + out_y1,
1920                                 w,
1921                                 out_y2 - out_y1,
1922                                 in_x2,
1923                                 in_y1,
1924                                 dst);
1925                 }
1926         }
1927
1928
1929
1930
1931
1932 // Segment 3
1933         draw_pixmap(src,
1934                 x + out_x3,
1935                 y + out_y1,
1936                 out_x4 - out_x3,
1937                 out_y2 - out_y1,
1938                 in_x3,
1939                 in_y1,
1940                 dst);
1941
1942
1943
1944 // Segment 4 * n
1945         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1946         {
1947                 if(out_y3 - i > 0)
1948                 {
1949                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1950                         draw_pixmap(src,
1951                                 x + out_x1,
1952                                 y + i,
1953                                 out_x2 - out_x1,
1954                                 h,
1955                                 in_x1,
1956                                 in_y2,
1957                                 dst);
1958                 }
1959         }
1960
1961
1962 // Segment 5 * n * n
1963         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2 /* in_y_third */)
1964         {
1965                 if(out_y3 - i > 0)
1966                 {
1967                         int h = MIN(in_y3 - in_y2 /* in_y_third */, out_y3 - i);
1968
1969
1970                         for(int j = out_x2; j < out_x3; j += in_x3 - in_x2 /* in_x_third */)
1971                         {
1972                                 int w = MIN(in_x3 - in_x2 /* in_x_third */, out_x3 - j);
1973                                 if(out_x3 - j > 0)
1974                                         draw_pixmap(src,
1975                                                 x + j,
1976                                                 y + i,
1977                                                 w,
1978                                                 h,
1979                                                 in_x2,
1980                                                 in_y2,
1981                                                 dst);
1982                         }
1983                 }
1984         }
1985
1986 // Segment 6 * n
1987         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1988         {
1989                 if(out_y3 - i > 0)
1990                 {
1991                         int h = MIN(in_y3 - in_y2, out_y3 - i);
1992                         draw_pixmap(src,
1993                                 x + out_x3,
1994                                 y + i,
1995                                 out_x4 - out_x3,
1996                                 h,
1997                                 in_x3,
1998                                 in_y2,
1999                                 dst);
2000                 }
2001         }
2002
2003
2004
2005
2006 // Segment 7
2007         draw_pixmap(src,
2008                 x + out_x1,
2009                 y + out_y3,
2010                 out_x2 - out_x1,
2011                 out_y4 - out_y3,
2012                 in_x1,
2013                 in_y3,
2014                 dst);
2015
2016
2017 // Segment 8 * n
2018         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
2019         {
2020                 if(out_x3 - i > 0)
2021                 {
2022                         int w = MIN(in_x3 - in_y2, out_x3 - i);
2023                         draw_pixmap(src,
2024                                 x + i,
2025                                 y + out_y3,
2026                                 w,
2027                                 out_y4 - out_y3,
2028                                 in_x2,
2029                                 in_y3,
2030                                 dst);
2031                 }
2032         }
2033
2034
2035
2036 // Segment 9
2037         draw_pixmap(src,
2038                 x + out_x3,
2039                 y + out_y3,
2040                 out_x4 - out_x3,
2041                 out_y4 - out_y3,
2042                 in_x3,
2043                 in_y3,
2044                 dst);
2045 }
2046
2047
2048 void BC_WindowBase::draw_9segment(int x,
2049                 int y,
2050                 int w,
2051                 int h,
2052                 VFrame *src,
2053                 BC_Pixmap *dst)
2054 {
2055         if(w <= 0 || h <= 0) return;
2056
2057         int in_x_third = src->get_w() / 3;
2058         int in_y_third = src->get_h() / 3;
2059         int out_x_half = w / 2;
2060         int out_y_half = h / 2;
2061
2062         int in_x1 = 0;
2063         int in_y1 = 0;
2064         int out_x1 = 0;
2065         int out_y1 = 0;
2066         int in_x2 = MIN(in_x_third, out_x_half);
2067         int in_y2 = MIN(in_y_third, out_y_half);
2068         int out_x2 = in_x2;
2069         int out_y2 = in_y2;
2070
2071         int out_x3 = MAX(w - out_x_half, w - in_x_third);
2072         int out_x4 = w;
2073         int in_x3 = src->get_w() - (out_x4 - out_x3);
2074         int in_x4 = src->get_w();
2075
2076         int out_y3 = MAX(h - out_y_half, h - in_y_third);
2077         int out_y4 = h;
2078         int in_y3 = src->get_h() - (out_y4 - out_y3);
2079         int in_y4 = src->get_h();
2080
2081 //printf("PFCFrame::draw_9segment 1 %d %d %d %d\n", out_x1, out_x2, out_x3, out_x4);
2082 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_x1, in_x2, in_x3, in_x4);
2083 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_y1, in_y2, in_y3, in_y4);
2084
2085         if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
2086                 src->get_w(),
2087                 src->get_h(),
2088                 get_color_model(),
2089                 0);
2090         temp_bitmap->match_params(src->get_w(),
2091                 src->get_h(),
2092                 get_color_model(),
2093                 0);
2094         temp_bitmap->read_frame(src,
2095                 0,
2096                 0,
2097                 src->get_w(),
2098                 src->get_h());
2099
2100 // Segment 1
2101         draw_bitmap(temp_bitmap,
2102                 0,
2103                 x + out_x1,
2104                 y + out_y1,
2105                 out_x2 - out_x1,
2106                 out_y2 - out_y1,
2107                 in_x1,
2108                 in_y1,
2109                 in_x2 - in_x1,
2110                 in_y2 - in_y1,
2111                 dst);
2112
2113
2114 // Segment 2 * n
2115         for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
2116         {
2117                 if(out_x3 - i > 0)
2118                 {
2119                         int w = MIN(in_x3 - in_x2, out_x3 - i);
2120                         draw_bitmap(temp_bitmap,
2121                                 0,
2122                                 x + i,
2123                                 y + out_y1,
2124                                 w,
2125                                 out_y2 - out_y1,
2126                                 in_x2,
2127                                 in_y1,
2128                                 w,
2129                                 in_y2 - in_y1,
2130                                 dst);
2131                 }
2132         }
2133
2134
2135
2136
2137
2138 // Segment 3
2139         draw_bitmap(temp_bitmap,
2140                 0,
2141                 x + out_x3,
2142                 y + out_y1,
2143                 out_x4 - out_x3,
2144                 out_y2 - out_y1,
2145                 in_x3,
2146                 in_y1,
2147                 in_x4 - in_x3,
2148                 in_y2 - in_y1,
2149                 dst);
2150
2151
2152
2153 // Segment 4 * n
2154         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
2155         {
2156                 if(out_y3 - i > 0)
2157                 {
2158                         int h = MIN(in_y3 - in_y2, out_y3 - i);
2159                         draw_bitmap(temp_bitmap,
2160                                 0,
2161                                 x + out_x1,
2162                                 y + i,
2163                                 out_x2 - out_x1,
2164                                 h,
2165                                 in_x1,
2166                                 in_y2,
2167                                 in_x2 - in_x1,
2168                                 h,
2169                                 dst);
2170                 }
2171         }
2172
2173
2174 // Segment 5 * n * n
2175         for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
2176         {
2177                 if(out_y3 - i > 0)
2178                 {
2179                         int h = MIN(in_y3 - in_y2, out_y3 - i);
2180
2181
2182                         for(int j = out_x2; j < out_x3; j += in_x3 - in_x2)
2183                         {
2184                                 int w = MIN(in_x3 - in_x2, out_x3 - j);
2185                                 if(out_x3 - j > 0)
2186                                         draw_bitmap(temp_bitmap,
2187                                                 0,
2188                                                 x + j,
2189                                                 y + i,
2190                                                 w,
2191                                                 h,
2192                                                 in_x2,
2193                                                 in_y2,
2194                                                 w,
2195                                                 h,
2196                                                 dst);
2197                         }
2198                 }
2199         }
2200
2201 // Segment 6 * n
2202         for(int i = out_y2; i < out_y3; i += in_y_third)
2203         {
2204                 if(out_y3 - i > 0)
2205                 {
2206                         int h = MIN(in_y_third, out_y3 - i);
2207                         draw_bitmap(temp_bitmap,
2208                                 0,
2209                                 x + out_x3,
2210                                 y + i,
2211                                 out_x4 - out_x3,
2212                                 h,
2213                                 in_x3,
2214                                 in_y2,
2215                                 in_x4 - in_x3,
2216                                 h,
2217                                 dst);
2218                 }
2219         }
2220
2221
2222
2223
2224 // Segment 7
2225         draw_bitmap(temp_bitmap,
2226                 0,
2227                 x + out_x1,
2228                 y + out_y3,
2229                 out_x2 - out_x1,
2230                 out_y4 - out_y3,
2231                 in_x1,
2232                 in_y3,
2233                 in_x2 - in_x1,
2234                 in_y4 - in_y3,
2235                 dst);
2236
2237
2238 // Segment 8 * n
2239         for(int i = out_x2; i < out_x3; i += in_x_third)
2240         {
2241                 if(out_x3 - i > 0)
2242                 {
2243                         int w = MIN(in_x_third, out_x3 - i);
2244                         draw_bitmap(temp_bitmap,
2245                                 0,
2246                                 x + i,
2247                                 y + out_y3,
2248                                 w,
2249                                 out_y4 - out_y3,
2250                                 in_x2,
2251                                 in_y3,
2252                                 w,
2253                                 in_y4 - in_y3,
2254                                 dst);
2255                 }
2256         }
2257
2258
2259
2260 // Segment 9
2261         draw_bitmap(temp_bitmap,
2262                 0,
2263                 x + out_x3,
2264                 y + out_y3,
2265                 out_x4 - out_x3,
2266                 out_y4 - out_y3,
2267                 in_x3,
2268                 in_y3,
2269                 in_x4 - in_x3,
2270                 in_y4 - in_y3,
2271                 dst);
2272 }
2273
2274
2275
2276
2277
2278
2279
2280
2281