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