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