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