4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
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.
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.
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
25 #include "bcresources.h"
26 #include "bcsignals.h"
27 #include "bcsynchronous.h"
29 #include "bcwindowbase.h"
39 #include "workarounds.h"
41 void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_Pixmap *pixmap)
43 XCopyArea(top_level->display,
44 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
45 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
46 top_level->gc, x1, y1, w, h, x2, y2);
50 void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
52 //if(x == 0) printf("BC_WindowBase::draw_box %d %d %d %d\n", x, y, w, h);
53 XFillRectangle(top_level->display,
54 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
55 top_level->gc, x, y, w, h);
59 void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
61 XDrawArc(top_level->display,
62 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
63 top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
66 void BC_WindowBase::draw_arc(int x, int y, int w, int h,
67 int start_angle, int angle_length, BC_Pixmap *pixmap)
69 XDrawArc(top_level->display,
70 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
71 top_level->gc, x, y, (w - 1), (h - 2), start_angle * 64,
75 void BC_WindowBase::draw_disc(int x, int y, int w, int h, BC_Pixmap *pixmap)
77 XFillArc(top_level->display,
78 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
79 top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
82 void BC_WindowBase::clear_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
85 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
86 XFillRectangle(top_level->display, xpixmap, top_level->gc, x, y, w, h);
89 void BC_WindowBase::draw_text_line(int x, int y, const char *text, int len,
93 if( get_resources()->use_xft ) {
94 draw_xft_text(x, y, text, len, pixmap);
99 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
100 if( get_resources()->use_fontset ) {
101 XFontSet fontset = top_level->get_curr_fontset();
103 XmbDrawString(top_level->display, xpixmap, fontset,
104 top_level->gc, x, y, text, len);
109 //printf("BC_WindowBase::draw_text 3\n");
110 XDrawString(top_level->display, xpixmap, top_level->gc, x, y, text, len);
113 void BC_WindowBase::draw_text(int x, int y, const char *text, int length,
116 if( length < 0 ) length = strlen(text);
117 //int boldface = top_level->current_font & BOLDFACE;
118 int font = top_level->current_font & 0xff;
120 switch(top_level->current_font) {
121 case MEDIUM_7SEGMENT:
122 for(int i = 0; i < length; i++) {
123 VFrame *image, **img7seg = get_resources()->medium_7segment;
126 case '0': case '1': case '2': case '3': case '4':
127 case '5': case '6': case '7': case '8': case '9':
128 image = img7seg[ch-'0']; break;
129 case ':': image = img7seg[10]; break;
130 case '.': image = img7seg[11]; break;
131 case 'a': case 'b': case 'c':
132 case 'd': case 'e': case 'f': ch -= 'a'-'A';
133 case 'A': case 'B': case 'C': /* fallthru */
134 case 'D': case 'E': case 'F':
135 image = img7seg[12+ch-'A']; break;
137 case '-': image = img7seg[19]; break;
139 case ' ': image = img7seg[18]; break;
142 draw_vframe(image, x, y - image->get_h());
148 if(top_level->get_xft_struct(top_level->current_font)) {
149 draw_xft_text(x, y, text, length, pixmap);
153 for(int i = 0, j = 0; i <= length; i++) {
154 if(text[i] == '\n' || text[i] == 0) {
155 if(get_resources()->use_fontset && top_level->get_curr_fontset()) {
156 XmbDrawString(top_level->display,
157 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
158 top_level->get_curr_fontset(),
159 top_level->gc, x, y, &text[j], i-j);
162 XDrawString(top_level->display,
163 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
164 top_level->gc, x, y, &text[j], i-j);
167 y += get_text_height(font);
174 void BC_WindowBase::draw_utf8_text(int x, int y,
175 const char *text, int length, BC_Pixmap *pixmap)
177 if(length < 0) length = strlen(text);
179 if(top_level->get_xft_struct(top_level->current_font))
190 for(int i = 0, j = 0; i <= length; i++)
192 if(text[i] == '\n' || text[i] == 0)
194 if(get_resources()->use_fontset && top_level->get_curr_fontset())
196 XmbDrawString(top_level->display,
197 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
198 top_level->get_curr_fontset(),
207 XDrawString(top_level->display,
208 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
217 y += get_text_height(MEDIUMFONT);
222 void BC_WindowBase::draw_xft_text(int x, int y,
223 const char *text, int length, BC_Pixmap *pixmap, int is_utf8)
226 wchar_t wide_text[l];
227 length = BC_Resources::encode(
228 is_utf8 ? "UTF8" : BC_Resources::encoding, BC_Resources::wide_encoding,
229 (char*)text, length, (char*)wide_text, l*sizeof(wchar_t)) / sizeof(wchar_t);
230 draw_xft_text(x, y, wide_text, length, pixmap);
233 void BC_WindowBase::draw_xft_text(int x, int y,
234 const wchar_t *text, int length, BC_Pixmap *pixmap)
237 const wchar_t *wsp = text, *wep = wsp + length;
238 int font = top_level->current_font;
240 const wchar_t *wcp = wsp;
241 while( wcp < wep && *wcp != '\n' ) ++wcp;
244 draw_single_text(1, font, x, y, wsp, len, pixmap);
245 if( wcp >= wep ) break;
247 dy = get_text_height(font);
253 void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
254 int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap)
256 Pixmap draw_pixmap = 0;
257 XftDraw *xft_draw = (XftDraw *)
258 (pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw);
259 int src_x = x, src_y = y, src_w = 0, src_h = 0;
261 XGetGCValues(top_level->display, top_level->gc, GCFunction, &values);
262 if( values.function != GXcopy ) {
263 XSetFunction(top_level->display, top_level->gc, GXcopy);
265 xftTextExtents32(top_level->display, xft_font, fc, len, &info);
266 src_w = info.width; src_h = info.height;
267 draw_pixmap = XCreatePixmap(top_level->display, top_level->win,
268 src_w, src_h, top_level->default_depth);
269 int color = get_color(); set_color(0);
270 XFillRectangle(top_level->display, draw_pixmap, top_level->gc, 0, 0, src_w, src_h);
272 xft_draw = xftDrawCreate(top_level->display, draw_pixmap,
273 top_level->vis, top_level->cmap);
274 src_x = info.x; src_y = info.y;
276 xftDrawString32(xft_draw, xft_color, xft_font, src_x, src_y, fc, len);
277 if( values.function != GXcopy ) {
278 XSetFunction(top_level->display, top_level->gc, values.function);
279 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
280 XCopyArea(top_level->display, draw_pixmap, xpixmap,
281 top_level->gc, 0, 0, src_w, src_h, x, y);
282 XFreePixmap(top_level->display, draw_pixmap);
283 xftDrawDestroy(xft_draw);
287 int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
289 return draw_single_text(0, font, 0,0, text, length);
292 int BC_WindowBase::draw_single_text(int draw, int font,
293 int x, int y, const wchar_t *text, int length, BC_Pixmap *pixmap)
296 length = wcslen(text);
297 if( !length ) return 0;
299 if( !get_resources()->use_xft ) {
301 if( !get_font_struct(font) ) return 0;
302 XChar2b xtext[length], *xp = xtext;
303 for( int i=0; i<length; ++i,++xp ) {
304 xp->byte1 = (unsigned char) (text[i] >> 8);
305 xp->byte2 = (unsigned char) (text[i] & 0xff);
308 XDrawString16(top_level->display,
309 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
310 top_level->gc, x, y, xtext, length);
312 return XTextWidth16(get_font_struct(font), xtext, length);
319 color.red = (top_level->current_color & 0xff0000) >> 16;
320 color.red |= color.red << 8;
321 color.green = (top_level->current_color & 0xff00) >> 8;
322 color.green |= color.green << 8;
323 color.blue = (top_level->current_color & 0xff);
324 color.blue |= color.blue << 8;
325 color.alpha = 0xffff;
327 xftColorAllocValue(top_level->display, top_level->vis, top_level->cmap,
332 XftFont *basefont = top_level->get_xft_struct(font);
333 XftFont *curfont = 0, *altfont = 0;
334 const wchar_t *up = text, *ubp = up, *uep = ubp + length;
337 XftFont *xft_font = 0;
338 if( xftCharExists(top_level->display, basefont, *up) )
341 if( xftCharExists(top_level->display, altfont, *up))
344 xftFontClose(top_level->display, altfont);
349 FcPattern *pattern = BC_Resources::find_similar_font(*up, basefont->pattern);
352 fcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE, 0, &psize);
353 fcPatternAddDouble(pattern, FC_PIXEL_SIZE, psize);
354 fcPatternDel(pattern, FC_SCALABLE);
355 xft_font = altfont = xftFontOpenPattern(top_level->display, pattern);
360 if( xft_font != curfont ) {
361 if( curfont && up > ubp ) {
363 xft_draw_string(&xft_color, curfont, x, y,
364 (const FcChar32*)ubp, up-ubp, pixmap);
367 xftTextExtents32(top_level->display, curfont,
368 (const FcChar32*)ubp, up-ubp, &extents);
371 ubp = up; curfont = xft_font;
376 if( curfont && up > ubp ) {
378 xft_draw_string(&xft_color, curfont, x, y,
379 (const FcChar32*)ubp, up-ubp, pixmap);
382 xftTextExtents32(top_level->display, curfont,
383 (const FcChar32*)ubp, up-ubp, &extents);
388 xftFontClose(top_level->display, altfont);
390 xftColorFree(top_level->display, top_level->vis, top_level->cmap, &xft_color);
395 void BC_WindowBase::truncate_text(char *result, const char *text, int w)
397 int new_w = get_text_width(current_font, text);
400 const char* separator = "...";
401 int separator_w = get_text_width(current_font, separator);
403 if( separator_w >= w ) {
404 strcpy(result, separator);
408 int text_len = strlen(text);
409 // widen middle gap until it fits
410 for( int i=text_len/2; i>0; --i ) {
411 strncpy(result, text, i);
413 strcat(result, separator);
414 strncat(result, text + text_len - i, i);
415 result[i + strlen(separator) + i] = 0;
416 new_w = get_text_width(current_font, result);
417 //printf("BC_WindowBase::truncate_text %d %d %d %s\n", __LINE__, new_w, w, result);
418 if(new_w < w) return;
422 strcpy(result, separator);
426 strcpy(result, text);
429 void BC_WindowBase::draw_center_text(int x, int y, const char *text, int length)
431 if(length < 0) length = strlen(text);
432 int w = get_text_width(current_font, text, length);
434 draw_text(x, y, text, length);
437 void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
439 // Some X drivers can't draw 0 length lines
440 if( x1 == x2 && y1 == y2 ) {
441 draw_pixel(x1, y1, pixmap);
444 XDrawLine(top_level->display,
445 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
446 top_level->gc, x1, y1, x2, y2);
450 void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
452 int npoints = MIN(x->total, y->total);
453 XPoint *points = new XPoint[npoints];
455 for( int i=0; i<npoints; ++i ) {
456 points[i].x = x->values[i];
457 points[i].y = y->values[i];
460 XDrawLines(top_level->display,
461 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
462 top_level->gc, points, npoints, CoordModeOrigin);
467 void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
469 int npoints = MIN(x->total, y->total);
470 XPoint *points = new XPoint[npoints];
472 for( int i=0; i<npoints; ++i ) {
473 points[i].x = x->values[i];
474 points[i].y = y->values[i];
477 XFillPolygon(top_level->display,
478 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
479 top_level->gc, points, npoints, Nonconvex, CoordModeOrigin);
485 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
487 XDrawRectangle(top_level->display,
488 pixmap->opaque_pixmap, top_level->gc,
492 void BC_WindowBase::draw_3d_border(int x, int y, int w, int h, int is_down)
494 draw_3d_border(x, y, w, h,
495 top_level->get_resources()->border_shadow2,
496 top_level->get_resources()->border_shadow1,
497 top_level->get_resources()->border_light1,
498 top_level->get_resources()->border_light2);
502 void BC_WindowBase::draw_3d_border(int x, int y, int w, int h,
503 int light1, int light2, int shadow1, int shadow2)
510 ux = x+w-1; uy = y+h-1;
513 draw_line(x, y, ux, y);
514 draw_line(x, y, x, uy);
516 draw_line(lx, ly, ux - 1, ly);
517 draw_line(lx, ly, lx, uy - 1);
520 draw_line(ux, ly, ux, uy);
521 draw_line(lx, uy, ux, uy);
523 draw_line(x + w, y, x + w, y + h);
524 draw_line(x, y + h, x + w, y + h);
527 void BC_WindowBase::draw_3d_box(int x, int y, int w, int h,
528 int light1, int light2, int middle, int shadow1, int shadow2,
536 ux = x+w-1; uy = y+h-1;
539 draw_box(x, y, w, h, pixmap);
542 draw_line(x, y, ux, y, pixmap);
543 draw_line(x, y, x, uy, pixmap);
545 draw_line(lx, ly, ux - 1, ly, pixmap);
546 draw_line(lx, ly, lx, uy - 1, pixmap);
549 draw_line(ux, ly, ux, uy, pixmap);
550 draw_line(lx, uy, ux, uy, pixmap);
552 draw_line(x + w, y, x + w, y + h, pixmap);
553 draw_line(x, y + h, x + w, y + h, pixmap);
556 void BC_WindowBase::draw_colored_box(int x, int y, int w, int h, int down, int highlighted)
561 draw_3d_box(x, y, w, h,
562 top_level->get_resources()->button_light,
563 top_level->get_resources()->button_highlighted,
564 top_level->get_resources()->button_highlighted,
565 top_level->get_resources()->button_shadow,
568 draw_3d_box(x, y, w, h,
569 top_level->get_resources()->button_light,
570 top_level->get_resources()->button_up,
571 top_level->get_resources()->button_up,
572 top_level->get_resources()->button_shadow,
577 // need highlighting for toggles
579 draw_3d_box(x, y, w, h,
580 top_level->get_resources()->button_shadow,
582 top_level->get_resources()->button_up,
583 top_level->get_resources()->button_up,
584 top_level->get_resources()->button_light);
586 draw_3d_box(x, y, w, h,
587 top_level->get_resources()->button_shadow,
589 top_level->get_resources()->button_down,
590 top_level->get_resources()->button_down,
591 top_level->get_resources()->button_light);
596 void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
598 int left_indent = 20;
602 lx = x + 1; ly = y + 1;
603 ux = x + w - 1; uy = y + h - 1;
606 if(text && text[0] != 0)
609 set_font(MEDIUMFONT);
610 draw_text(x + left_indent, y + get_text_height(MEDIUMFONT) / 2, text);
613 set_color(top_level->get_resources()->button_shadow);
614 draw_line(x, y, x + left_indent - 5, y);
615 draw_line(x, y, x, uy);
616 draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), y, ux, y);
617 draw_line(x, y, x, uy);
618 draw_line(ux, ly, ux, uy);
619 draw_line(lx, uy, ux, uy);
620 set_color(top_level->get_resources()->button_light);
621 draw_line(lx, ly, x + left_indent - 5 - 1, ly);
622 draw_line(lx, ly, lx, uy - 1);
623 draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), ly, ux - 1, ly);
624 draw_line(lx, ly, lx, uy - 1);
625 draw_line(x + w, y, x + w, y + h);
626 draw_line(x, y + h, x + w, y + h);
629 void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
631 int x1, y1, x2, y2, x3;
634 x1 = x+1; x2 = x + w/2; x3 = x+w-1;
637 point[0].x = x2; point[0].y = y2;
638 point[1].x = x3; point[1].y = y1;
639 point[2].x = x1; point[2].y = y1;
641 XFillPolygon(top_level->display,
642 pixmap->opaque_pixmap,
648 draw_line(x1,y1, x3,y1);
651 void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h,
652 int light1, int light2, int middle, int shadow1, int shadow2)
654 int x1, y1, x2, y2, x3;
657 x1 = x; y1 = y; x2 = x + w / 2;
658 y2 = y + h - 1; x3 = x + w - 1;
661 point[0].x = x2; point[0].y = y1; point[1].x = x3;
662 point[1].y = y2; point[2].x = x1; point[2].y = y2;
665 XFillPolygon(top_level->display,
666 pixmap->opaque_pixmap,
673 // bottom and top right
675 draw_line(x3, y2-1, x1, y2-1);
676 draw_line(x2-1, y1, x3-1, y2);
678 draw_line(x3, y2, x1, y2);
679 draw_line(x2, y1, x3, y2);
683 draw_line(x2+1, y1, x1+1, y2);
685 draw_line(x2, y1, x1, y2);
688 void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h,
689 int light1, int light2, int middle, int shadow1, int shadow2)
691 int x1, y1, x2, y2, x3;
694 x1 = x; x2 = x + w / 2; x3 = x + w - 1;
695 y1 = y; y2 = y + h - 1;
697 point[0].x = x2; point[0].y = y2; point[1].x = x3;
698 point[1].y = y1; point[2].x = x1; point[2].y = y1;
701 XFillPolygon(top_level->display,
702 pixmap->opaque_pixmap,
709 // top and bottom left
711 draw_line(x3-1, y1+1, x1+1, y1+1);
712 draw_line(x1+1, y1, x2+1, y2);
714 draw_line(x3, y1, x1, y1);
715 draw_line(x1, y1, x2, y2);
719 draw_line(x3-1, y1, x2-1, y2);
721 draw_line(x3, y1, x2, y2);
724 void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
725 int light1, int light2, int middle, int shadow1, int shadow2)
727 int x1, y1, x2, y2, y3;
731 y1 = y; x1 = x; y2 = y + h / 2;
732 x2 = x + w - 1; y3 = y + h - 1;
734 point[0].x = x1; point[0].y = y2; point[1].x = x2;
735 point[1].y = y1; point[2].x = x2; point[2].y = y3;
738 XFillPolygon(top_level->display,
739 pixmap->opaque_pixmap,
746 // right and bottom right
748 draw_line(x2-1, y1, x2-1, y3-1);
749 draw_line(x2, y3-1, x1, y2-1);
751 draw_line(x2, y1, x2, y3);
752 draw_line(x2, y3, x1, y2);
756 draw_line(x1, y2, x2, y1);
758 draw_line(x1, y2+1, x2, y1+1);
761 void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h,
762 int light1, int light2, int middle, int shadow1, int shadow2)
764 int x1, y1, x2, y2, y3;
767 y1 = y; y2 = y + h / 2; y3 = y + h - 1;
768 x1 = x; x2 = x + w - 1;
770 point[0].x = x1; point[0].y = y1; point[1].x = x2;
771 point[1].y = y2; point[2].x = x1; point[2].y = y3;
774 XFillPolygon(top_level->display,
775 pixmap->opaque_pixmap,
782 // left and top right
784 draw_line(x1+1, y3, x1+1, y1);
785 draw_line(x1, y1+1, x2, y2+1);
787 draw_line(x1, y3, x1, y1);
788 draw_line(x1, y1, x2, y2);
792 draw_line(x2, y2-1, x1, y3-1);
794 draw_line(x2, y2, x1, y3);
798 void BC_WindowBase::draw_check(int x, int y)
800 const int w = 15, h = 15;
801 draw_line(x + 3, y + h / 2 + 0, x + 6, y + h / 2 + 2);
802 draw_line(x + 3, y + h / 2 + 1, x + 6, y + h / 2 + 3);
803 draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
804 draw_line(x + 3, y + h / 2 + 2, x + 6, y + h / 2 + 4);
805 draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
806 draw_line(x + 6, y + h / 2 + 3, x + w - 4, y + h / 2 - 2);
807 draw_line(x + 6, y + h / 2 + 4, x + w - 4, y + h / 2 - 1);
810 void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
814 draw_box(x, y, w, h);
817 XSetFillStyle(top_level->display, top_level->gc, FillTiled);
818 // Don't know how slow this is
819 XSetTile(top_level->display, top_level->gc, tile->get_pixmap());
820 XSetTSOrigin(top_level->display, top_level->gc, origin_x, origin_y);
821 draw_box(x, y, w, h);
822 XSetFillStyle(top_level->display, top_level->gc, FillSolid);
826 void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
829 int origin_x, origin_y;
830 XTranslateCoordinates(top_level->display,
831 parent_window->win, win,
832 0, 0, &origin_x, &origin_y, &tempwin);
833 draw_tiles(parent_window->bg_pixmap,
838 void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window,
839 int x, int y, int w, int h, BC_Pixmap *pixmap)
843 XLockDisplay(top_level->display);
845 XTranslateCoordinates(top_level->display,
846 win, parent_window->win,
847 x, y, &top_x, &top_y, &tempwin);
849 XCopyArea(top_level->display,
850 parent_window->pixmap->opaque_pixmap,
851 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
852 top_level->gc, top_x, top_y, w, h, x, y);
854 XUnlockDisplay(top_level->display);
857 void BC_WindowBase::draw_background(int x, int y, int w, int h)
860 draw_tiles(bg_pixmap, 0, 0, x, y, w, h);
863 clear_box(x, y, w, h);
867 void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap, int dont_wait,
868 int dest_x, int dest_y, int dest_w, int dest_h,
869 int src_x, int src_y, int src_w, int src_h,
872 // Hide cursor if video enabled
873 update_video_cursor();
875 //printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y);
876 if( dest_w <= 0 || dest_h <= 0 ) {
877 // Use hardware scaling to canvas dimensions if proper color model.
878 if( bitmap->get_color_model() == BC_YUV420P ) {
883 dest_w = bitmap->get_w();
884 dest_h = bitmap->get_h();
888 if( src_w <= 0 || src_h <= 0 ) {
889 src_w = bitmap->get_w();
890 src_h = bitmap->get_h();
894 bitmap->write_drawable(win,
895 top_level->gc, src_x, src_y, src_w, src_h,
896 dest_x, dest_y, dest_w, dest_h, dont_wait);
900 bitmap->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
901 top_level->gc, dest_x, dest_y, src_x, src_y, dest_w, dest_h, dont_wait);
903 //printf("BC_WindowBase::draw_bitmap 2\n");
907 void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
909 XDrawPoint(top_level->display,
910 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
911 top_level->gc, x, y);
915 void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap,
916 int dest_x, int dest_y, int dest_w, int dest_h,
917 int src_x, int src_y, BC_Pixmap *dst)
919 pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
920 dest_x, dest_y, dest_w, dest_h, src_x, src_y);
923 void BC_WindowBase::draw_vframe(VFrame *frame,
924 int dest_x, int dest_y, int dest_w, int dest_h,
925 int src_x, int src_y, int src_w, int src_h,
928 if(dest_w <= 0) dest_w = frame->get_w() - src_x;
929 if(dest_h <= 0) dest_h = frame->get_h() - src_y;
930 if(src_w <= 0) src_w = frame->get_w() - src_x;
931 if(src_h <= 0) src_h = frame->get_h() - src_y;
932 CLAMP(src_x, 0, frame->get_w() - 1);
933 CLAMP(src_y, 0, frame->get_h() - 1);
934 if(src_x + src_w > frame->get_w()) src_w = frame->get_w() - src_x;
935 if(src_y + src_h > frame->get_h()) src_h = frame->get_h() - src_y;
938 temp_bitmap = new BC_Bitmap(this, dest_w, dest_h, get_color_model(), 0);
939 temp_bitmap->match_params(dest_w, dest_h, get_color_model(), 0);
941 temp_bitmap->read_frame(frame,
942 src_x, src_y, src_w, src_h,
943 0, 0, dest_w, dest_h, bg_color);
945 draw_bitmap(temp_bitmap, 0,
946 dest_x, dest_y, dest_w, dest_h,
947 0, 0, -1, -1, pixmap);
950 void BC_WindowBase::draw_tooltip(const char *text)
954 if(tooltip_popup && text)
956 int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
957 tooltip_popup->set_color(get_resources()->tooltip_bg_color);
958 tooltip_popup->draw_box(0, 0, w, h);
959 tooltip_popup->set_color(BLACK);
960 tooltip_popup->draw_rectangle(0, 0, w, h);
961 tooltip_popup->set_font(MEDIUMFONT);
962 tooltip_popup->draw_text(TOOLTIP_MARGIN,
963 get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN,
968 void BC_WindowBase::slide_left(int distance)
972 XCopyArea(top_level->display,
973 pixmap->opaque_pixmap,
974 pixmap->opaque_pixmap,
985 void BC_WindowBase::slide_right(int distance)
989 XCopyArea(top_level->display,
990 pixmap->opaque_pixmap,
991 pixmap->opaque_pixmap,
1002 void BC_WindowBase::slide_up(int distance)
1006 XCopyArea(top_level->display,
1007 pixmap->opaque_pixmap,
1008 pixmap->opaque_pixmap,
1016 set_color(bg_color);
1017 XFillRectangle(top_level->display,
1018 pixmap->opaque_pixmap,
1027 void BC_WindowBase::slide_down(int distance)
1031 XCopyArea(top_level->display,
1032 pixmap->opaque_pixmap,
1033 pixmap->opaque_pixmap,
1041 set_color(bg_color);
1042 XFillRectangle(top_level->display,
1043 pixmap->opaque_pixmap,
1052 // 3 segments in separate pixmaps. Obsolete.
1053 void BC_WindowBase::draw_3segment(int x,
1057 BC_Pixmap *left_image,
1058 BC_Pixmap *mid_image,
1059 BC_Pixmap *right_image,
1062 if(w <= 0 || h <= 0) return;
1063 int left_boundary = left_image->get_w_fixed();
1064 int right_boundary = w - right_image->get_w_fixed();
1065 for(int i = 0; i < w; )
1069 if(i < left_boundary)
1072 if(i < right_boundary)
1075 image = right_image;
1077 int output_w = image->get_w_fixed();
1079 if(i < left_boundary)
1081 if(i + output_w > left_boundary) output_w = left_boundary - i;
1084 if(i < right_boundary)
1086 if(i + output_w > right_boundary) output_w = right_boundary - i;
1089 if(i + output_w > w) output_w = w - i;
1091 image->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1102 // 3 segments in separate vframes. Obsolete.
1103 void BC_WindowBase::draw_3segment(int x,
1109 VFrame *right_image,
1112 if(w <= 0 || h <= 0) return;
1113 int left_boundary = left_image->get_w_fixed();
1114 int right_boundary = w - right_image->get_w_fixed();
1117 for(int i = 0; i < w; )
1121 if(i < left_boundary)
1124 if(i < right_boundary)
1127 image = right_image;
1129 int output_w = image->get_w_fixed();
1131 if(i < left_boundary)
1133 if(i + output_w > left_boundary) output_w = left_boundary - i;
1136 if(i < right_boundary)
1138 if(i + output_w > right_boundary) output_w = right_boundary - i;
1141 if(i + output_w > w) output_w = w - i;
1155 if(output_w == 0) break;
1160 // Draw all 3 segments in a single vframe for a changing level
1165 // <------------------------------------------------------------>
1169 // <-------------------------------------------------------------------->
1171 // |-------------------|----------------------|------------------|
1174 void BC_WindowBase::draw_3segmenth(int x,
1189 void BC_WindowBase::draw_3segmenth(int x, int y, int w,
1190 int total_x, int total_w, VFrame *image,
1193 if(total_w <= 0 || w <= 0 || h <= 0) return;
1194 int third_image = image->get_w() / 3;
1195 int half_image = image->get_w() / 2;
1196 //int left_boundary = third_image;
1197 //int right_boundary = total_w - third_image;
1199 int left_in_w = third_image;
1200 int left_out_x = total_x;
1201 int left_out_w = third_image;
1202 int right_in_x = image->get_w() - third_image;
1203 int right_in_w = third_image;
1204 int right_out_x = total_x + total_w - third_image;
1205 int right_out_w = third_image;
1206 int center_out_x = total_x + third_image;
1207 int center_out_w = total_w - third_image * 2;
1208 //int image_x, image_w;
1210 //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",
1211 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1215 left_in_w -= x - left_out_x;
1216 left_out_w -= x - left_out_x;
1217 left_in_x += x - left_out_x;
1218 left_out_x += x - left_out_x;
1221 if(left_out_x + left_out_w > x + w)
1223 left_in_w -= (left_out_x + left_out_w) - (x + w);
1224 left_out_w -= (left_out_x + left_out_w) - (x + w);
1229 right_in_w -= x - right_out_x;
1230 right_out_w -= x - right_out_x;
1231 right_in_x += x - right_out_x;
1232 right_out_x += x - right_out_x;
1235 if(right_out_x + right_out_w > x + w)
1237 right_in_w -= (right_out_x + right_out_w) - (x + w);
1238 right_out_w -= (right_out_x + right_out_w) - (x + w);
1241 if(center_out_x < x)
1243 center_out_w -= x - center_out_x;
1244 center_out_x += x - center_out_x;
1247 if(center_out_x + center_out_w > x + w)
1249 center_out_w -= (center_out_x + center_out_w) - (x + w);
1252 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1253 image->get_w(), image->get_h(),
1254 get_color_model(), 0);
1255 temp_bitmap->match_params(image->get_w(), image->get_h(),
1256 get_color_model(), 0);
1257 temp_bitmap->read_frame(image,
1258 0, 0, image->get_w(), image->get_h(), bg_color);
1259 // src width and height are meaningless in video_off mode
1260 //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",
1261 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1262 if(left_out_w > 0) {
1263 draw_bitmap(temp_bitmap, 0,
1264 left_out_x, y, left_out_w, image->get_h(),
1265 left_in_x, 0, -1, -1, pixmap);
1268 if(right_out_w > 0) {
1269 draw_bitmap(temp_bitmap, 0,
1270 right_out_x, y, right_out_w, image->get_h(),
1271 right_in_x, 0, -1, -1, pixmap);
1274 for( int pixel = center_out_x;
1275 pixel < center_out_x + center_out_w;
1276 pixel += half_image ) {
1277 int fragment_w = half_image;
1278 if(fragment_w + pixel > center_out_x + center_out_w)
1279 fragment_w = (center_out_x + center_out_w) - pixel;
1281 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1282 draw_bitmap(temp_bitmap, 0,
1283 pixel, y, fragment_w, image->get_h(),
1284 third_image, 0, -1, -1, pixmap);
1289 void BC_WindowBase::draw_3segmenth(int x, int y, int w, int total_x, int total_w,
1290 BC_Pixmap *src, BC_Pixmap *dst)
1292 if(w <= 0 || total_w <= 0) return;
1293 if(!src) printf("BC_WindowBase::draw_3segmenth src=0\n");
1294 int quarter_src = src->get_w() / 4;
1295 int half_src = src->get_w() / 2;
1296 //int left_boundary = quarter_src;
1297 //int right_boundary = total_w - quarter_src;
1299 int left_in_w = quarter_src;
1300 int left_out_x = total_x;
1301 int left_out_w = quarter_src;
1302 int right_in_x = src->get_w() - quarter_src;
1303 int right_in_w = quarter_src;
1304 int right_out_x = total_x + total_w - quarter_src;
1305 int right_out_w = quarter_src;
1306 int center_out_x = total_x + quarter_src;
1307 int center_out_w = total_w - quarter_src * 2;
1310 //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",
1311 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1315 left_in_w -= x - left_out_x;
1316 left_out_w -= x - left_out_x;
1317 left_in_x += x - left_out_x;
1318 left_out_x += x - left_out_x;
1321 if(left_out_x + left_out_w > x + w)
1323 left_in_w -= (left_out_x + left_out_w) - (x + w);
1324 left_out_w -= (left_out_x + left_out_w) - (x + w);
1329 right_in_w -= x - right_out_x;
1330 right_out_w -= x - right_out_x;
1331 right_in_x += x - right_out_x;
1332 right_out_x += x - right_out_x;
1335 if(right_out_x + right_out_w > x + w)
1337 right_in_w -= (right_out_x + right_out_w) - (x + w);
1338 right_out_w -= (right_out_x + right_out_w) - (x + w);
1341 if(center_out_x < x)
1343 center_out_w -= x - center_out_x;
1344 center_out_x += x - center_out_x;
1347 if(center_out_x + center_out_w > x + w)
1349 center_out_w -= (center_out_x + center_out_w) - (x + w);
1353 //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",
1354 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1379 for(int pixel = center_out_x;
1380 pixel < center_out_x + center_out_w;
1383 int fragment_w = half_src;
1384 if(fragment_w + pixel > center_out_x + center_out_w)
1385 fragment_w = (center_out_x + center_out_w) - pixel;
1387 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1401 void BC_WindowBase::draw_3segmenth(int x,
1408 int third_image = src->get_w() / 3;
1409 int half_output = w / 2;
1410 //int left_boundary = third_image;
1411 //int right_boundary = w - third_image;
1413 int left_in_w = third_image;
1415 int left_out_w = third_image;
1416 int right_in_x = src->get_w() - third_image;
1417 int right_in_w = third_image;
1418 int right_out_x = x + w - third_image;
1419 int right_out_w = third_image;
1420 //int image_x, image_w;
1422 //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",
1423 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1425 if(left_out_w > half_output)
1427 left_in_w -= left_out_w - half_output;
1428 left_out_w -= left_out_w - half_output;
1431 if(right_out_x < x + half_output)
1433 right_in_w -= x + half_output - right_out_x;
1434 right_out_w -= x + half_output - right_out_x;
1435 right_in_x += x + half_output - right_out_x;
1436 right_out_x += x + half_output - right_out_x;
1439 //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",
1440 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1465 for(int pixel = left_out_x + left_out_w;
1466 pixel < right_out_x;
1467 pixel += third_image)
1469 int fragment_w = third_image;
1470 if(fragment_w + pixel > right_out_x)
1471 fragment_w = right_out_x - pixel;
1473 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1492 void BC_WindowBase::draw_3segmentv(int x,
1499 int third_image = src->get_h() / 3;
1500 int half_output = h / 2;
1501 //int left_boundary = third_image;
1502 //int right_boundary = h - third_image;
1504 int left_in_h = third_image;
1506 int left_out_h = third_image;
1507 int right_in_y = src->get_h() - third_image;
1508 int right_in_h = third_image;
1509 int right_out_y = y + h - third_image;
1510 int right_out_h = third_image;
1511 //int image_y, image_h;
1514 if(left_out_h > half_output)
1516 left_in_h -= left_out_h - half_output;
1517 left_out_h -= left_out_h - half_output;
1520 if(right_out_y < y + half_output)
1522 right_in_h -= y + half_output - right_out_y;
1523 right_out_h -= y + half_output - right_out_y;
1524 right_in_y += y + half_output - right_out_y;
1525 right_out_y += y + half_output - right_out_y;
1529 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1534 temp_bitmap->match_params(src->get_w(),
1538 temp_bitmap->read_frame(src,
1539 0, 0, src->get_w(), src->get_h(), bg_color);
1544 draw_bitmap(temp_bitmap,
1559 draw_bitmap(temp_bitmap,
1572 for(int pixel = left_out_y + left_out_h;
1573 pixel < right_out_y;
1574 pixel += third_image)
1576 int fragment_h = third_image;
1577 if(fragment_h + pixel > right_out_y)
1578 fragment_h = right_out_y - pixel;
1580 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1581 draw_bitmap(temp_bitmap,
1595 void BC_WindowBase::draw_3segmentv(int x,
1602 int third_image = src->get_h() / 3;
1603 int half_output = h / 2;
1604 //int left_boundary = third_image;
1605 //int right_boundary = h - third_image;
1607 int left_in_h = third_image;
1609 int left_out_h = third_image;
1610 int right_in_y = src->get_h() - third_image;
1611 int right_in_h = third_image;
1612 int right_out_y = y + h - third_image;
1613 int right_out_h = third_image;
1614 //int image_y, image_h;
1617 if(left_out_h > half_output)
1619 left_in_h -= left_out_h - half_output;
1620 left_out_h -= left_out_h - half_output;
1623 if(right_out_y < y + half_output)
1625 right_in_h -= y + half_output - right_out_y;
1626 right_out_h -= y + half_output - right_out_y;
1627 right_in_y += y + half_output - right_out_y;
1628 right_out_y += y + half_output - right_out_y;
1655 for(int pixel = left_out_y + left_out_h;
1656 pixel < right_out_y;
1657 pixel += third_image)
1659 int fragment_h = third_image;
1660 if(fragment_h + pixel > right_out_y)
1661 fragment_h = right_out_y - pixel;
1663 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1676 void BC_WindowBase::draw_9segment(int x,
1683 if(w <= 0 || h <= 0) return;
1685 int in_x_third = src->get_w() / 3;
1686 int in_y_third = src->get_h() / 3;
1687 int out_x_half = w / 2;
1688 int out_y_half = h / 2;
1694 int in_x2 = MIN(in_x_third, out_x_half);
1695 int in_y2 = MIN(in_y_third, out_y_half);
1699 int out_x3 = MAX(w - out_x_half, w - in_x_third);
1701 int in_x3 = src->get_w() - (out_x4 - out_x3);
1702 //int in_x4 = src->get_w();
1704 int out_y3 = MAX(h - out_y_half, h - in_y_third);
1706 int in_y3 = src->get_h() - (out_y4 - out_y3);
1707 //int in_y4 = src->get_h();
1721 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1725 int w = MIN(in_x3 - in_x2, out_x3 - i);
1754 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1758 int h = MIN(in_y3 - in_y2, out_y3 - i);
1771 // Segment 5 * n * n
1772 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2 /* in_y_third */)
1776 int h = MIN(in_y3 - in_y2 /* in_y_third */, out_y3 - i);
1779 for(int j = out_x2; j < out_x3; j += in_x3 - in_x2 /* in_x_third */)
1781 int w = MIN(in_x3 - in_x2 /* in_x_third */, out_x3 - j);
1796 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1800 int h = MIN(in_y3 - in_y2, out_y3 - i);
1827 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1831 int w = MIN(in_x3 - in_y2, out_x3 - i);
1857 void BC_WindowBase::draw_9segment(int x, int y, int w, int h,
1858 VFrame *src, BC_Pixmap *dst)
1860 if(w <= 0 || h <= 0) return;
1862 int in_x_third = src->get_w() / 3;
1863 int in_y_third = src->get_h() / 3;
1864 int out_x_half = w / 2;
1865 int out_y_half = h / 2;
1871 int in_x2 = MIN(in_x_third, out_x_half);
1872 int in_y2 = MIN(in_y_third, out_y_half);
1876 int out_x3 = MAX(w - out_x_half, w - in_x_third);
1878 int in_x3 = src->get_w() - (out_x4 - out_x3);
1879 int in_x4 = src->get_w();
1881 int out_y3 = MAX(h - out_y_half, h - in_y_third);
1883 int in_y3 = src->get_h() - (out_y4 - out_y3);
1884 int in_y4 = src->get_h();
1886 //printf("PFCFrame::draw_9segment 1 %d %d %d %d\n", out_x1, out_x2, out_x3, out_x4);
1887 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_x1, in_x2, in_x3, in_x4);
1888 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_y1, in_y2, in_y3, in_y4);
1890 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1895 temp_bitmap->match_params(src->get_w(),
1899 temp_bitmap->read_frame(src,
1900 0, 0, src->get_w(), src->get_h(), bg_color);
1903 draw_bitmap(temp_bitmap, 0,
1904 x + out_x1, y + out_y1, out_x2 - out_x1, out_y2 - out_y1,
1905 in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1,
1909 for( int i = out_x2; i < out_x3; i += in_x3 - in_x2 ) {
1910 if( out_x3 - i > 0 ) {
1911 int w = MIN(in_x3 - in_x2, out_x3 - i);
1912 draw_bitmap(temp_bitmap, 0,
1913 x + i, y + out_y1, w, out_y2 - out_y1,
1914 in_x2, in_y1, w, in_y2 - in_y1,
1920 draw_bitmap(temp_bitmap, 0,
1921 x + out_x3, y + out_y1, out_x4 - out_x3, out_y2 - out_y1,
1922 in_x3, in_y1, in_x4 - in_x3, in_y2 - in_y1,
1926 for( int i = out_y2; i < out_y3; i += in_y3 - in_y2 ) {
1927 if( out_y3 - i > 0 ) {
1928 int h = MIN(in_y3 - in_y2, out_y3 - i);
1929 draw_bitmap(temp_bitmap, 0,
1930 x + out_x1, y + i, out_x2 - out_x1, h,
1931 in_x1, in_y2, in_x2 - in_x1, h,
1936 // Segment 5 * n * n
1937 for( int i = out_y2; i < out_y3; i += in_y3 - in_y2 ) {
1938 if( out_y3 - i > 0 ) {
1939 int h = MIN(in_y3 - in_y2, out_y3 - i);
1941 for( int j = out_x2; j < out_x3; j += in_x3 - in_x2 ) {
1942 int w = MIN(in_x3 - in_x2, out_x3 - j);
1944 draw_bitmap(temp_bitmap, 0,
1953 for( int i = out_y2; i < out_y3; i += in_y_third ) {
1954 if( out_y3 - i > 0 ) {
1955 int h = MIN(in_y_third, out_y3 - i);
1956 draw_bitmap(temp_bitmap, 0,
1957 x + out_x3, y + i, out_x4 - out_x3, h,
1958 in_x3, in_y2, in_x4 - in_x3, h,
1964 draw_bitmap(temp_bitmap, 0,
1965 x + out_x1, y + out_y3, out_x2 - out_x1, out_y4 - out_y3,
1966 in_x1, in_y3, in_x2 - in_x1, in_y4 - in_y3,
1970 for( int i = out_x2; i < out_x3; i += in_x_third ) {
1971 if( out_x3 - i > 0 ) {
1972 int w = MIN(in_x_third, out_x3 - i);
1973 draw_bitmap(temp_bitmap, 0,
1974 x + i, y + out_y3, w, out_y4 - out_y3,
1975 in_x2, in_y3, w, in_y4 - in_y3,
1981 draw_bitmap(temp_bitmap, 0,
1982 x + out_x3, y + out_y3, out_x4 - out_x3, out_y4 - out_y3,
1983 in_x3, in_y3, in_x4 - in_x3, in_y4 - in_y3,