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