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))
181 draw_xft_text(x, y, text, length, pixmap, 1);
185 for(int i = 0, j = 0; i <= length; i++)
187 if(text[i] == '\n' || text[i] == 0)
189 if(get_resources()->use_fontset && top_level->get_curr_fontset())
191 XmbDrawString(top_level->display,
192 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
193 top_level->get_curr_fontset(), top_level->gc,
194 x, y, &text[j], i - j);
198 XDrawString(top_level->display,
199 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
201 x, y, &text[j], i - j);
205 y += get_text_height(MEDIUMFONT);
210 void BC_WindowBase::draw_xft_text(int x, int y,
211 const char *text, int length, BC_Pixmap *pixmap, int is_utf8)
215 length = BC_Resources::encode(
216 is_utf8 ? "UTF8" : BC_Resources::encoding, BC_Resources::wide_encoding,
217 (char*)text, length, (char*)wide_text, l*sizeof(wchr_t)) / sizeof(wchr_t);
218 draw_xft_text(x, y, wide_text, length, pixmap);
221 void BC_WindowBase::draw_xft_text(int x, int y,
222 const wchr_t *text, int length, BC_Pixmap *pixmap)
225 const wchr_t *wsp = text, *wep = wsp + length;
226 int font = top_level->current_font;
228 const wchr_t *wcp = wsp;
229 while( wcp < wep && *wcp != '\n' ) ++wcp;
232 draw_single_text(1, font, x, y, wsp, len, pixmap);
233 if( wcp >= wep ) break;
235 dy = get_text_height(font);
241 void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
242 int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap)
244 Pixmap draw_pixmap = 0;
245 XftDraw *xft_draw = (XftDraw *)
246 (pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw);
247 int src_x = x, src_y = y, src_w = 0, src_h = 0;
249 XGetGCValues(top_level->display, top_level->gc, GCFunction, &values);
250 if( values.function != GXcopy ) {
251 XSetFunction(top_level->display, top_level->gc, GXcopy);
253 xftTextExtents32(top_level->display, xft_font, fc, len, &info);
254 src_w = info.width; src_h = info.height;
255 draw_pixmap = XCreatePixmap(top_level->display, top_level->win,
256 src_w, src_h, top_level->default_depth);
257 int color = get_color(); set_color(0);
258 XFillRectangle(top_level->display, draw_pixmap, top_level->gc, 0, 0, src_w, src_h);
260 xft_draw = xftDrawCreate(top_level->display, draw_pixmap,
261 top_level->vis, top_level->cmap);
262 src_x = info.x; src_y = info.y;
264 xftDrawString32(xft_draw, xft_color, xft_font, src_x, src_y, fc, len);
265 if( values.function != GXcopy ) {
266 XSetFunction(top_level->display, top_level->gc, values.function);
267 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
268 XCopyArea(top_level->display, draw_pixmap, xpixmap,
269 top_level->gc, 0, 0, src_w, src_h, x, y);
270 XFreePixmap(top_level->display, draw_pixmap);
271 xftDrawDestroy(xft_draw);
275 int BC_WindowBase::get_single_text_width(int font, const wchr_t *text, int length)
277 return draw_single_text(0, font, 0,0, text, length);
280 int BC_WindowBase::draw_single_text(int draw, int font,
281 int x, int y, const wchr_t *text, int length, BC_Pixmap *pixmap)
284 length = wstrlen(text);
285 if( !length ) return 0;
287 if( !get_resources()->use_xft ) {
289 if( !get_font_struct(font) ) return 0;
290 XChar2b xtext[length], *xp = xtext;
291 for( int i=0; i<length; ++i,++xp ) {
292 xp->byte1 = (unsigned char) (text[i] >> 8);
293 xp->byte2 = (unsigned char) (text[i] & 0xff);
296 XDrawString16(top_level->display,
297 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
298 top_level->gc, x, y, xtext, length);
300 return XTextWidth16(get_font_struct(font), xtext, length);
307 color.red = (top_level->current_color & 0xff0000) >> 16;
308 color.red |= color.red << 8;
309 color.green = (top_level->current_color & 0xff00) >> 8;
310 color.green |= color.green << 8;
311 color.blue = (top_level->current_color & 0xff);
312 color.blue |= color.blue << 8;
313 color.alpha = 0xffff;
315 xftColorAllocValue(top_level->display, top_level->vis, top_level->cmap,
320 XftFont *basefont = top_level->get_xft_struct(font);
321 XftFont *curfont = 0, *altfont = 0;
322 const wchr_t *up = text, *ubp = up, *uep = ubp + length;
325 XftFont *xft_font = 0;
326 if( xftCharExists(top_level->display, basefont, *up) )
329 if( xftCharExists(top_level->display, altfont, *up))
332 xftFontClose(top_level->display, altfont);
337 FcPattern *pattern = BC_Resources::find_similar_font(*up, basefont->pattern);
340 fcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE, 0, &psize);
341 fcPatternAddDouble(pattern, FC_PIXEL_SIZE, psize);
342 fcPatternDel(pattern, FC_SCALABLE);
343 xft_font = altfont = xftFontOpenPattern(top_level->display, pattern);
348 if( xft_font != curfont ) {
349 if( curfont && up > ubp ) {
351 xft_draw_string(&xft_color, curfont, x, y,
352 (const FcChar32*)ubp, up-ubp, pixmap);
355 xftTextExtents32(top_level->display, curfont,
356 (const FcChar32*)ubp, up-ubp, &extents);
359 ubp = up; curfont = xft_font;
364 if( curfont && up > ubp ) {
366 xft_draw_string(&xft_color, curfont, x, y,
367 (const FcChar32*)ubp, up-ubp, pixmap);
370 xftTextExtents32(top_level->display, curfont,
371 (const FcChar32*)ubp, up-ubp, &extents);
376 xftFontClose(top_level->display, altfont);
378 xftColorFree(top_level->display, top_level->vis, top_level->cmap, &xft_color);
383 void BC_WindowBase::draw_center_text(int x, int y, const char *text, int length)
385 if(length < 0) length = strlen(text);
386 int w = get_text_width(current_font, text, length);
388 draw_text(x, y, text, length);
391 void BC_WindowBase::draw_pix(int x, int y, BC_Pixmap *pixmap)
392 { // draw_pixel, no BT test
393 XDrawPoint(top_level->display,
394 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
395 top_level->gc, x, y);
398 void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
400 // Some X drivers can't draw 0 length lines
401 if( x1 == x2 && y1 == y2 ) {
402 draw_pix(x1, y1, pixmap);
405 XDrawLine(top_level->display,
406 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
407 top_level->gc, x1, y1, x2, y2);
411 void BC_WindowBase::draw_bline(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
413 // Short lines are all overhead to hw or sw setup, use bresenhams
415 int tx = x1; x1 = x2; x2 = tx;
416 int ty = y1; y1 = y2; y2 = ty;
420 int dx = x2-x1, dy = y2-y1;
421 int dx2 = 2*dx, dy2 = 2*dy;
422 if( dx < 0 ) dx = -dx;
423 int r = dx > dy ? dx : dy, n = r;
425 if( dx2 < 0 ) dir += 1;
427 if( dx2 >= 0 ) do { /* +Y, +X */
428 draw_pix(x, y++, pixmap);
429 if( (r -= dx2) < 0 ) { r += dy2; ++x; }
431 else do { /* +Y, -X */
432 draw_pix(x, y++, pixmap);
433 if( (r += dx2) < 0 ) { r += dy2; --x; }
437 if( dx2 >= 0 ) do { /* +X, +Y */
438 draw_pix(x++, y, pixmap);
439 if( (r -= dy2) < 0 ) { r += dx2; ++y; }
441 else do { /* -X, +Y */
442 draw_pix(x--, y, pixmap);
443 if( (r -= dy2) < 0 ) { r -= dx2; ++y; }
448 void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
450 int npoints = MIN(x->total, y->total);
451 XPoint *points = new XPoint[npoints];
453 for( int i=0; i<npoints; ++i ) {
454 points[i].x = x->values[i];
455 points[i].y = y->values[i];
458 XDrawLines(top_level->display,
459 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
460 top_level->gc, points, npoints, CoordModeOrigin);
465 void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
467 int npoints = MIN(x->total, y->total);
468 XPoint *points = new XPoint[npoints];
470 for( int i=0; i<npoints; ++i ) {
471 points[i].x = x->values[i];
472 points[i].y = y->values[i];
475 XFillPolygon(top_level->display,
476 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
477 top_level->gc, points, npoints, Nonconvex, CoordModeOrigin);
483 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
485 XDrawRectangle(top_level->display,
486 pixmap->opaque_pixmap, top_level->gc,
490 void BC_WindowBase::draw_3d_border(int x, int y, int w, int h, int is_down)
492 draw_3d_border(x, y, w, h,
493 top_level->get_resources()->border_shadow2,
494 top_level->get_resources()->border_shadow1,
495 top_level->get_resources()->border_light1,
496 top_level->get_resources()->border_light2);
500 void BC_WindowBase::draw_3d_border(int x, int y, int w, int h,
501 int light1, int light2, int shadow1, int shadow2)
508 ux = x+w-1; uy = y+h-1;
511 draw_line(x, y, ux, y);
512 draw_line(x, y, x, uy);
514 draw_line(lx, ly, ux - 1, ly);
515 draw_line(lx, ly, lx, uy - 1);
518 draw_line(ux, ly, ux, uy);
519 draw_line(lx, uy, ux, uy);
521 draw_line(x + w, y, x + w, y + h);
522 draw_line(x, y + h, x + w, y + h);
525 void BC_WindowBase::draw_3d_box(int x, int y, int w, int h,
526 int light1, int light2, int middle, int shadow1, int shadow2,
534 ux = x+w-1; uy = y+h-1;
537 draw_box(x, y, w, h, pixmap);
540 draw_line(x, y, ux, y, pixmap);
541 draw_line(x, y, x, uy, pixmap);
543 draw_line(lx, ly, ux - 1, ly, pixmap);
544 draw_line(lx, ly, lx, uy - 1, pixmap);
547 draw_line(ux, ly, ux, uy, pixmap);
548 draw_line(lx, uy, ux, uy, pixmap);
550 draw_line(x + w, y, x + w, y + h, pixmap);
551 draw_line(x, y + h, x + w, y + h, pixmap);
554 void BC_WindowBase::draw_colored_box(int x, int y, int w, int h, int down, int highlighted)
559 draw_3d_box(x, y, w, h,
560 top_level->get_resources()->button_light,
561 top_level->get_resources()->button_highlighted,
562 top_level->get_resources()->button_highlighted,
563 top_level->get_resources()->button_shadow,
566 draw_3d_box(x, y, w, h,
567 top_level->get_resources()->button_light,
568 top_level->get_resources()->button_up,
569 top_level->get_resources()->button_up,
570 top_level->get_resources()->button_shadow,
575 // need highlighting for toggles
577 draw_3d_box(x, y, w, h,
578 top_level->get_resources()->button_shadow,
580 top_level->get_resources()->button_up,
581 top_level->get_resources()->button_up,
582 top_level->get_resources()->button_light);
584 draw_3d_box(x, y, w, h,
585 top_level->get_resources()->button_shadow,
587 top_level->get_resources()->button_down,
588 top_level->get_resources()->button_down,
589 top_level->get_resources()->button_light);
594 void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
596 int left_indent = xS(20);
600 lx = x + 1; ly = y + 1;
601 ux = x + w - 1; uy = y + h - 1;
604 if(text && text[0] != 0)
607 set_font(MEDIUMFONT);
608 draw_text(x + left_indent, y + get_text_height(MEDIUMFONT) / 2, text);
611 set_color(top_level->get_resources()->button_shadow);
612 draw_line(x, y, x + left_indent - xS(5), y);
613 draw_line(x, y, x, uy);
614 draw_line(x + left_indent + xS(5) + get_text_width(MEDIUMFONT, text), y, ux, y);
615 draw_line(x, y, x, uy);
616 draw_line(ux, ly, ux, uy);
617 draw_line(lx, uy, ux, uy);
618 set_color(top_level->get_resources()->button_light);
619 draw_line(lx, ly, x + left_indent - xS(5) - 1, ly);
620 draw_line(lx, ly, lx, uy - 1);
621 draw_line(x + left_indent + xS(5) + get_text_width(MEDIUMFONT, text), ly, ux - 1, ly);
622 draw_line(lx, ly, lx, uy - 1);
623 draw_line(x + w, y, x + w, y + h);
624 draw_line(x, y + h, x + w, y + h);
627 void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
629 int x1, y1, x2, y2, x3;
632 x1 = x+1; x2 = x + w/2; x3 = x+w-1;
635 point[0].x = x2; point[0].y = y2;
636 point[1].x = x3; point[1].y = y1;
637 point[2].x = x1; point[2].y = y1;
639 XFillPolygon(top_level->display, pixmap->opaque_pixmap, top_level->gc,
640 (XPoint *)point, 3, Nonconvex, CoordModeOrigin);
641 draw_line(x1,y1, x3,y1);
644 void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h,
645 int light1, int light2, int middle, int shadow1, int shadow2)
647 int x1, y1, x2, y2, x3;
650 x1 = x; y1 = y; x2 = x + w / 2;
651 y2 = y + h - 1; x3 = x + w - 1;
654 point[0].x = x2; point[0].y = y1; point[1].x = x3;
655 point[1].y = y2; point[2].x = x1; point[2].y = y2;
658 XFillPolygon(top_level->display, pixmap->opaque_pixmap, top_level->gc,
659 (XPoint *)point, 3, Nonconvex, CoordModeOrigin);
661 // bottom and top right
663 draw_line(x3, y2-1, x1, y2-1);
664 draw_line(x2-1, y1, x3-1, y2);
666 draw_line(x3, y2, x1, y2);
667 draw_line(x2, y1, x3, y2);
671 draw_line(x2+1, y1, x1+1, y2);
673 draw_line(x2, y1, x1, y2);
676 void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h,
677 int light1, int light2, int middle, int shadow1, int shadow2)
679 int x1, y1, x2, y2, x3;
682 x1 = x; x2 = x + w / 2; x3 = x + w - 1;
683 y1 = y; y2 = y + h - 1;
685 point[0].x = x2; point[0].y = y2; point[1].x = x3;
686 point[1].y = y1; point[2].x = x1; point[2].y = y1;
689 XFillPolygon(top_level->display,
690 pixmap->opaque_pixmap,
697 // top and bottom left
699 draw_line(x3-1, y1+1, x1+1, y1+1);
700 draw_line(x1+1, y1, x2+1, y2);
702 draw_line(x3, y1, x1, y1);
703 draw_line(x1, y1, x2, y2);
707 draw_line(x3-1, y1, x2-1, y2);
709 draw_line(x3, y1, x2, y2);
712 void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
713 int light1, int light2, int middle, int shadow1, int shadow2)
715 int x1, y1, x2, y2, y3;
719 y1 = y; x1 = x; y2 = y + h / 2;
720 x2 = x + w - 1; y3 = y + h - 1;
722 point[0].x = x1; point[0].y = y2; point[1].x = x2;
723 point[1].y = y1; point[2].x = x2; point[2].y = y3;
726 XFillPolygon(top_level->display,
727 pixmap->opaque_pixmap,
734 // right and bottom right
736 draw_line(x2-1, y1, x2-1, y3-1);
737 draw_line(x2, y3-1, x1, y2-1);
739 draw_line(x2, y1, x2, y3);
740 draw_line(x2, y3, x1, y2);
744 draw_line(x1, y2, x2, y1);
746 draw_line(x1, y2+1, x2, y1+1);
749 void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h,
750 int light1, int light2, int middle, int shadow1, int shadow2)
752 int x1, y1, x2, y2, y3;
755 y1 = y; y2 = y + h / 2; y3 = y + h - 1;
756 x1 = x; x2 = x + w - 1;
758 point[0].x = x1; point[0].y = y1; point[1].x = x2;
759 point[1].y = y2; point[2].x = x1; point[2].y = y3;
762 XFillPolygon(top_level->display,
763 pixmap->opaque_pixmap,
770 // left and top right
772 draw_line(x1+1, y3, x1+1, y1);
773 draw_line(x1, y1+1, x2, y2+1);
775 draw_line(x1, y3, x1, y1);
776 draw_line(x1, y1, x2, y2);
780 draw_line(x2, y2-1, x1, y3-1);
782 draw_line(x2, y2, x1, y3);
786 void BC_WindowBase::draw_check(int x, int y)
788 int xs3 = xS(3), xs4 = xS(4), xs6 = xS(6);
789 int ys1 = yS(1), ys2 = yS(2), ys3 = yS(3), ys4 = yS(4);
790 const int w = xS(15), h = yS(15), yh2 = y + h/2;
791 draw_line(x + xs3, yh2 + 0, x + xs6, yh2 + ys2);
792 draw_line(x + xs3, yh2 + ys1, x + xs6, yh2 + ys3);
793 draw_line(x + xs6, yh2 + ys2, x + w - xs4, yh2 - ys3);
794 draw_line(x + xs3, yh2 + ys2, x + xs6, yh2 + ys4);
795 draw_line(x + xs6, yh2 + ys2, x + w - xs4, yh2 - ys3);
796 draw_line(x + xs6, yh2 + ys3, x + w - xs4, yh2 - ys2);
797 draw_line(x + xs6, yh2 + ys4, x + w - xs4, yh2 - ys1);
800 void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
804 draw_box(x, y, w, h);
807 XSetFillStyle(top_level->display, top_level->gc, FillTiled);
808 // Don't know how slow this is
809 XSetTile(top_level->display, top_level->gc, tile->get_pixmap());
810 XSetTSOrigin(top_level->display, top_level->gc, origin_x, origin_y);
811 draw_box(x, y, w, h);
812 XSetFillStyle(top_level->display, top_level->gc, FillSolid);
816 void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
819 int origin_x, origin_y;
820 XTranslateCoordinates(top_level->display,
821 parent_window->win, win,
822 0, 0, &origin_x, &origin_y, &tempwin);
823 draw_tiles(parent_window->bg_pixmap,
828 void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window,
829 int x, int y, int w, int h, BC_Pixmap *pixmap)
833 XLockDisplay(top_level->display);
835 XTranslateCoordinates(top_level->display,
836 win, parent_window->win,
837 x, y, &top_x, &top_y, &tempwin);
839 XCopyArea(top_level->display,
840 parent_window->pixmap->opaque_pixmap,
841 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
842 top_level->gc, top_x, top_y, w, h, x, y);
844 XUnlockDisplay(top_level->display);
847 void BC_WindowBase::draw_background(int x, int y, int w, int h)
850 draw_tiles(bg_pixmap, 0, 0, x, y, w, h);
853 clear_box(x, y, w, h);
857 void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap, int dont_wait,
858 int dest_x, int dest_y, int dest_w, int dest_h,
859 int src_x, int src_y, int src_w, int src_h,
862 // Hide cursor if video enabled
863 update_video_cursor();
865 //printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y);
866 if( dest_w <= 0 || dest_h <= 0 ) {
867 // Use hardware scaling to canvas dimensions if proper color model.
868 if( bitmap->get_color_model() == BC_YUV420P ) {
873 dest_w = bitmap->get_w();
874 dest_h = bitmap->get_h();
878 if( src_w <= 0 || src_h <= 0 ) {
879 src_w = bitmap->get_w();
880 src_h = bitmap->get_h();
884 bitmap->write_drawable(win,
885 top_level->gc, src_x, src_y, src_w, src_h,
886 dest_x, dest_y, dest_w, dest_h, dont_wait);
890 bitmap->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
891 top_level->gc, dest_x, dest_y, src_x, src_y, dest_w, dest_h, dont_wait);
893 //printf("BC_WindowBase::draw_bitmap 2\n");
897 void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
899 XDrawPoint(top_level->display,
900 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
901 top_level->gc, x, y);
905 void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap,
906 int dest_x, int dest_y, int dest_w, int dest_h,
907 int src_x, int src_y, BC_Pixmap *dst)
909 pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
910 dest_x, dest_y, dest_w, dest_h, src_x, src_y);
913 void BC_WindowBase::draw_vframe(VFrame *frame,
914 int dest_x, int dest_y, int dest_w, int dest_h,
915 int src_x, int src_y, int src_w, int src_h,
918 if(dest_w <= 0) dest_w = frame->get_w() - src_x;
919 if(dest_h <= 0) dest_h = frame->get_h() - src_y;
920 if(src_w <= 0) src_w = frame->get_w() - src_x;
921 if(src_h <= 0) src_h = frame->get_h() - src_y;
922 CLAMP(src_x, 0, frame->get_w() - 1);
923 CLAMP(src_y, 0, frame->get_h() - 1);
924 if(src_x + src_w > frame->get_w()) src_w = frame->get_w() - src_x;
925 if(src_y + src_h > frame->get_h()) src_h = frame->get_h() - src_y;
928 temp_bitmap = new BC_Bitmap(this, dest_w, dest_h, get_color_model(), 0);
929 temp_bitmap->match_params(dest_w, dest_h, get_color_model(), 0);
931 temp_bitmap->read_frame(frame,
932 src_x, src_y, src_w, src_h,
933 0, 0, dest_w, dest_h, bg_color);
935 draw_bitmap(temp_bitmap, 0,
936 dest_x, dest_y, dest_w, dest_h,
937 0, 0, -1, -1, pixmap);
940 void BC_WindowBase::draw_tooltip(const char *text)
944 if(tooltip_popup && text)
946 int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
947 tooltip_popup->set_color(get_resources()->tooltip_bg_color);
948 tooltip_popup->draw_box(0, 0, w, h);
949 tooltip_popup->set_color(BLACK);
950 tooltip_popup->draw_rectangle(0, 0, w, h);
951 tooltip_popup->set_font(MEDIUMFONT);
952 tooltip_popup->draw_text(TOOLTIP_MARGIN,
953 get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN,
958 void BC_WindowBase::slide_left(int distance)
962 XCopyArea(top_level->display,
963 pixmap->opaque_pixmap,
964 pixmap->opaque_pixmap,
975 void BC_WindowBase::slide_right(int distance)
979 XCopyArea(top_level->display,
980 pixmap->opaque_pixmap, pixmap->opaque_pixmap, top_level->gc,
981 0, 0, w - distance, h, distance, 0);
985 void BC_WindowBase::slide_up(int distance)
989 XCopyArea(top_level->display,
990 pixmap->opaque_pixmap, pixmap->opaque_pixmap, top_level->gc,
991 0, distance, w, h - distance, 0, 0);
993 XFillRectangle(top_level->display, pixmap->opaque_pixmap, top_level->gc,
994 0, h - distance, w, distance);
998 void BC_WindowBase::slide_down(int distance)
1002 XCopyArea(top_level->display,
1003 pixmap->opaque_pixmap, pixmap->opaque_pixmap, top_level->gc,
1004 0, 0, w, h - distance, 0, distance);
1005 set_color(bg_color);
1006 XFillRectangle(top_level->display,
1007 pixmap->opaque_pixmap, top_level->gc,
1012 // 3 segments in separate pixmaps. Obsolete.
1013 void BC_WindowBase::draw_3segment(int x, int y, int w, int h,
1014 BC_Pixmap *left_image, BC_Pixmap *mid_image,
1015 BC_Pixmap *right_image, BC_Pixmap *pixmap)
1017 if(w <= 0 || h <= 0) return;
1018 int left_boundary = left_image->get_w_fixed();
1019 int right_boundary = w - right_image->get_w_fixed();
1020 for(int i = 0; i < w; )
1024 if(i < left_boundary)
1027 if(i < right_boundary)
1030 image = right_image;
1032 int output_w = image->get_w_fixed();
1034 if(i < left_boundary)
1036 if(i + output_w > left_boundary) output_w = left_boundary - i;
1039 if(i < right_boundary)
1041 if(i + output_w > right_boundary) output_w = right_boundary - i;
1044 if(i + output_w > w) output_w = w - i;
1046 image->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1047 x + i, y, output_w, h, 0, 0);
1051 // 3 segments in separate vframes. Obsolete.
1052 void BC_WindowBase::draw_3segment(int x, int y, int w, int h,
1053 VFrame *left_image, VFrame *mid_image,
1054 VFrame *right_image, BC_Pixmap *pixmap)
1056 if(w <= 0 || h <= 0) return;
1057 int left_boundary = left_image->get_w_fixed();
1058 int right_boundary = w - right_image->get_w_fixed();
1061 for(int i = 0; i < w; )
1065 if(i < left_boundary)
1068 if(i < right_boundary)
1071 image = right_image;
1073 int output_w = image->get_w_fixed();
1075 if(i < left_boundary)
1077 if(i + output_w > left_boundary) output_w = left_boundary - i;
1080 if(i < right_boundary)
1082 if(i + output_w > right_boundary) output_w = right_boundary - i;
1085 if(i + output_w > w) output_w = w - i;
1088 draw_vframe(image, x + i, y, output_w, h,
1089 0, 0, 0, 0, pixmap);
1091 if(output_w == 0) break;
1096 // Draw all 3 segments in a single vframe for a changing level
1101 // <------------------------------------------------------------>
1105 // <-------------------------------------------------------------------->
1107 // |-------------------|----------------------|------------------|
1110 void BC_WindowBase::draw_3segmenth(int x, int y, int w,
1111 VFrame *image, BC_Pixmap *pixmap)
1113 draw_3segmenth(x, y, w, x, w, image, pixmap);
1116 void BC_WindowBase::draw_3segmenth(int x, int y, int w,
1117 int total_x, int total_w, VFrame *image,
1120 if(total_w <= 0 || w <= 0 || h <= 0) return;
1121 int third_image = image->get_w() / 3;
1122 int half_image = image->get_w() / 2;
1123 //int left_boundary = third_image;
1124 //int right_boundary = total_w - third_image;
1126 int left_in_w = third_image;
1127 int left_out_x = total_x;
1128 int left_out_w = third_image;
1129 int right_in_x = image->get_w() - third_image;
1130 int right_in_w = third_image;
1131 int right_out_x = total_x + total_w - third_image;
1132 int right_out_w = third_image;
1133 int center_out_x = total_x + third_image;
1134 int center_out_w = total_w - third_image * 2;
1135 //int image_x, image_w;
1137 //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",
1138 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1142 left_in_w -= x - left_out_x;
1143 left_out_w -= x - left_out_x;
1144 left_in_x += x - left_out_x;
1145 left_out_x += x - left_out_x;
1148 if(left_out_x + left_out_w > x + w)
1150 left_in_w -= (left_out_x + left_out_w) - (x + w);
1151 left_out_w -= (left_out_x + left_out_w) - (x + w);
1156 right_in_w -= x - right_out_x;
1157 right_out_w -= x - right_out_x;
1158 right_in_x += x - right_out_x;
1159 right_out_x += x - right_out_x;
1162 if(right_out_x + right_out_w > x + w)
1164 right_in_w -= (right_out_x + right_out_w) - (x + w);
1165 right_out_w -= (right_out_x + right_out_w) - (x + w);
1168 if(center_out_x < x)
1170 center_out_w -= x - center_out_x;
1171 center_out_x += x - center_out_x;
1174 if(center_out_x + center_out_w > x + w)
1176 center_out_w -= (center_out_x + center_out_w) - (x + w);
1179 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1180 image->get_w(), image->get_h(),
1181 get_color_model(), 0);
1182 temp_bitmap->match_params(image->get_w(), image->get_h(),
1183 get_color_model(), 0);
1184 temp_bitmap->read_frame(image,
1185 0, 0, image->get_w(), image->get_h(), bg_color);
1186 // src width and height are meaningless in video_off mode
1187 //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",
1188 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1189 if(left_out_w > 0) {
1190 draw_bitmap(temp_bitmap, 0,
1191 left_out_x, y, left_out_w, image->get_h(),
1192 left_in_x, 0, -1, -1, pixmap);
1195 if(right_out_w > 0) {
1196 draw_bitmap(temp_bitmap, 0,
1197 right_out_x, y, right_out_w, image->get_h(),
1198 right_in_x, 0, -1, -1, pixmap);
1201 for( int pixel = center_out_x;
1202 pixel < center_out_x + center_out_w;
1203 pixel += half_image ) {
1204 int fragment_w = half_image;
1205 if(fragment_w + pixel > center_out_x + center_out_w)
1206 fragment_w = (center_out_x + center_out_w) - pixel;
1208 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1209 draw_bitmap(temp_bitmap, 0,
1210 pixel, y, fragment_w, image->get_h(),
1211 third_image, 0, -1, -1, pixmap);
1216 void BC_WindowBase::draw_3segmenth(int x, int y, int w, int total_x, int total_w,
1217 BC_Pixmap *src, BC_Pixmap *dst)
1219 if(w <= 0 || total_w <= 0) return;
1220 if(!src) printf("BC_WindowBase::draw_3segmenth src=0\n");
1221 int quarter_src = src->get_w() / 4;
1222 int half_src = src->get_w() / 2;
1223 //int left_boundary = quarter_src;
1224 //int right_boundary = total_w - quarter_src;
1226 int left_in_w = quarter_src;
1227 int left_out_x = total_x;
1228 int left_out_w = quarter_src;
1229 int right_in_x = src->get_w() - quarter_src;
1230 int right_in_w = quarter_src;
1231 int right_out_x = total_x + total_w - quarter_src;
1232 int right_out_w = quarter_src;
1233 int center_out_x = total_x + quarter_src;
1234 int center_out_w = total_w - quarter_src * 2;
1237 //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",
1238 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1242 left_in_w -= x - left_out_x;
1243 left_out_w -= x - left_out_x;
1244 left_in_x += x - left_out_x;
1245 left_out_x += x - left_out_x;
1248 if(left_out_x + left_out_w > x + w)
1250 left_in_w -= (left_out_x + left_out_w) - (x + w);
1251 left_out_w -= (left_out_x + left_out_w) - (x + w);
1256 right_in_w -= x - right_out_x;
1257 right_out_w -= x - right_out_x;
1258 right_in_x += x - right_out_x;
1259 right_out_x += x - right_out_x;
1262 if(right_out_x + right_out_w > x + w)
1264 right_in_w -= (right_out_x + right_out_w) - (x + w);
1265 right_out_w -= (right_out_x + right_out_w) - (x + w);
1268 if(center_out_x < x)
1270 center_out_w -= x - center_out_x;
1271 center_out_x += x - center_out_x;
1274 if(center_out_x + center_out_w > x + w)
1276 center_out_w -= (center_out_x + center_out_w) - (x + w);
1280 //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",
1281 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1283 draw_pixmap(src, left_out_x, y, left_out_w, src->get_h(), left_in_x, 0, dst);
1286 draw_pixmap(src, right_out_x, y, right_out_w, src->get_h(), right_in_x, 0, dst);
1288 for( int pixel = center_out_x; pixel < center_out_x + center_out_w; pixel += half_src) {
1289 int fragment_w = half_src;
1290 if(fragment_w + pixel > center_out_x + center_out_w)
1291 fragment_w = (center_out_x + center_out_w) - pixel;
1292 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1293 draw_pixmap(src, pixel, y, fragment_w, src->get_h(), quarter_src, 0, dst);
1299 void BC_WindowBase::draw_3segmenth(int x, int y, int w, BC_Pixmap *src, BC_Pixmap *dst)
1302 int third_image = src->get_w() / 3;
1303 int half_output = w / 2;
1304 //int left_boundary = third_image;
1305 //int right_boundary = w - third_image;
1307 int left_in_w = third_image;
1309 int left_out_w = third_image;
1310 int right_in_x = src->get_w() - third_image;
1311 int right_in_w = third_image;
1312 int right_out_x = x + w - third_image;
1313 int right_out_w = third_image;
1314 //int image_x, image_w;
1316 //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",
1317 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1319 if(left_out_w > half_output)
1321 left_in_w -= left_out_w - half_output;
1322 left_out_w -= left_out_w - half_output;
1325 if(right_out_x < x + half_output)
1327 right_in_w -= x + half_output - right_out_x;
1328 right_out_w -= x + half_output - right_out_x;
1329 right_in_x += x + half_output - right_out_x;
1330 right_out_x += x + half_output - right_out_x;
1333 //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",
1334 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1336 draw_pixmap(src, left_out_x, y, left_out_w, src->get_h(), left_in_x, 0, dst);
1339 draw_pixmap(src, right_out_x, y, right_out_w, src->get_h(), right_in_x, 0, dst);
1341 for(int pixel = left_out_x + left_out_w; pixel < right_out_x; pixel += third_image) {
1342 int fragment_w = third_image;
1343 if(fragment_w + pixel > right_out_x)
1344 fragment_w = right_out_x - pixel;
1346 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1347 draw_pixmap(src, pixel, y, fragment_w, src->get_h(), third_image, 0, dst);
1352 void BC_WindowBase::draw_3segmentv(int x, int y, int h, VFrame *src, BC_Pixmap *dst)
1355 int third_image = src->get_h() / 3;
1356 int half_output = h / 2;
1357 //int left_boundary = third_image;
1358 //int right_boundary = h - third_image;
1360 int left_in_h = third_image;
1362 int left_out_h = third_image;
1363 int right_in_y = src->get_h() - third_image;
1364 int right_in_h = third_image;
1365 int right_out_y = y + h - third_image;
1366 int right_out_h = third_image;
1367 //int image_y, image_h;
1370 if(left_out_h > half_output)
1372 left_in_h -= left_out_h - half_output;
1373 left_out_h -= left_out_h - half_output;
1376 if(right_out_y < y + half_output)
1378 right_in_h -= y + half_output - right_out_y;
1379 right_out_h -= y + half_output - right_out_y;
1380 right_in_y += y + half_output - right_out_y;
1381 right_out_y += y + half_output - right_out_y;
1385 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1390 temp_bitmap->match_params(src->get_w(),
1394 temp_bitmap->read_frame(src,
1395 0, 0, src->get_w(), src->get_h(), bg_color);
1400 draw_bitmap(temp_bitmap, 0, x, left_out_y,
1401 src->get_w(), left_out_h, 0, left_in_y,
1407 draw_bitmap(temp_bitmap, 0, x, right_out_y,
1408 src->get_w(), right_out_h, 0, right_in_y,
1412 for(int pixel = left_out_y + left_out_h;
1413 pixel < right_out_y;
1414 pixel += third_image)
1416 int fragment_h = third_image;
1417 if(fragment_h + pixel > right_out_y)
1418 fragment_h = right_out_y - pixel;
1420 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1421 draw_bitmap(temp_bitmap, 0, x, pixel,
1422 src->get_w(), fragment_h, 0, third_image,
1427 void BC_WindowBase::draw_3segmentv(int x,
1434 int third_image = src->get_h() / 3;
1435 int half_output = h / 2;
1436 //int left_boundary = third_image;
1437 //int right_boundary = h - third_image;
1439 int left_in_h = third_image;
1441 int left_out_h = third_image;
1442 int right_in_y = src->get_h() - third_image;
1443 int right_in_h = third_image;
1444 int right_out_y = y + h - third_image;
1445 int right_out_h = third_image;
1446 //int image_y, image_h;
1449 if(left_out_h > half_output)
1451 left_in_h -= left_out_h - half_output;
1452 left_out_h -= left_out_h - half_output;
1455 if(right_out_y < y + half_output)
1457 right_in_h -= y + half_output - right_out_y;
1458 right_out_h -= y + half_output - right_out_y;
1459 right_in_y += y + half_output - right_out_y;
1460 right_out_y += y + half_output - right_out_y;
1464 draw_pixmap(src, x, left_out_y, src->get_w(), left_out_h,
1468 draw_pixmap(src, x, right_out_y, src->get_w(), right_out_h,
1469 0, right_in_y, dst);
1471 for(int pixel = left_out_y + left_out_h; pixel < right_out_y; pixel += third_image) {
1472 int fragment_h = third_image;
1473 if(fragment_h + pixel > right_out_y)
1474 fragment_h = right_out_y - pixel;
1476 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1477 draw_pixmap(src, x, pixel, src->get_w(), fragment_h,
1478 0, third_image, dst);
1483 void BC_WindowBase::draw_9segment(int x, int y, int w, int h,
1484 BC_Pixmap *src, BC_Pixmap *dst)
1486 if(w <= 0 || h <= 0) return;
1488 int in_x_third = src->get_w() / 3;
1489 int in_y_third = src->get_h() / 3;
1490 int out_x_half = w / 2;
1491 int out_y_half = h / 2;
1497 int in_x2 = MIN(in_x_third, out_x_half);
1498 int in_y2 = MIN(in_y_third, out_y_half);
1502 int out_x3 = MAX(w - out_x_half, w - in_x_third);
1504 int in_x3 = src->get_w() - (out_x4 - out_x3);
1505 //int in_x4 = src->get_w();
1507 int out_y3 = MAX(h - out_y_half, h - in_y_third);
1509 int in_y3 = src->get_h() - (out_y4 - out_y3);
1510 //int in_y4 = src->get_h();
1513 draw_pixmap(src, x + out_x1, y + out_y1, out_x2 - out_x1, out_y2 - out_y1,
1517 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2) {
1518 if(out_x3 - i > 0) {
1519 int w = MIN(in_x3 - in_x2, out_x3 - i);
1520 draw_pixmap(src, x + i, y + out_y1, w, out_y2 - out_y1,
1526 draw_pixmap(src, x + out_x3, y + out_y1, out_x4 - out_x3, out_y2 - out_y1,
1530 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1534 int h = MIN(in_y3 - in_y2, out_y3 - i);
1535 draw_pixmap(src, x + out_x1, y + i, out_x2 - out_x1, h,
1540 // Segment 5 * n * n
1541 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2 /* in_y_third */)
1545 int h = MIN(in_y3 - in_y2 /* in_y_third */, out_y3 - i);
1548 for(int j = out_x2; j < out_x3; j += in_x3 - in_x2 /* in_x_third */)
1550 int w = MIN(in_x3 - in_x2 /* in_x_third */, out_x3 - j);
1552 draw_pixmap(src, x + j, y + i, w, h,
1559 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1563 int h = MIN(in_y3 - in_y2, out_y3 - i);
1564 draw_pixmap(src, x + out_x3, y + i, out_x4 - out_x3, h,
1570 draw_pixmap(src, x + out_x1, y + out_y3, out_x2 - out_x1, out_y4 - out_y3,
1574 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1578 int w = MIN(in_x3 - in_y2, out_x3 - i);
1579 draw_pixmap(src, x + i, y + out_y3, w, out_y4 - out_y3,
1585 draw_pixmap(src, x + out_x3, y + out_y3, out_x4 - out_x3, out_y4 - out_y3,
1590 void BC_WindowBase::draw_9segment(int x, int y, int w, int h,
1591 VFrame *src, BC_Pixmap *dst)
1593 if(w <= 0 || h <= 0) return;
1595 int in_x_third = src->get_w() / 3;
1596 int in_y_third = src->get_h() / 3;
1597 int out_x_half = w / 2;
1598 int out_y_half = h / 2;
1604 int in_x2 = MIN(in_x_third, out_x_half);
1605 int in_y2 = MIN(in_y_third, out_y_half);
1609 int out_x3 = MAX(w - out_x_half, w - in_x_third);
1611 int in_x3 = src->get_w() - (out_x4 - out_x3);
1612 int in_x4 = src->get_w();
1614 int out_y3 = MAX(h - out_y_half, h - in_y_third);
1616 int in_y3 = src->get_h() - (out_y4 - out_y3);
1617 int in_y4 = src->get_h();
1619 //printf("PFCFrame::draw_9segment 1 %d %d %d %d\n", out_x1, out_x2, out_x3, out_x4);
1620 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_x1, in_x2, in_x3, in_x4);
1621 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_y1, in_y2, in_y3, in_y4);
1623 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1628 temp_bitmap->match_params(src->get_w(),
1632 temp_bitmap->read_frame(src,
1633 0, 0, src->get_w(), src->get_h(), bg_color);
1636 draw_bitmap(temp_bitmap, 0,
1637 x + out_x1, y + out_y1, out_x2 - out_x1, out_y2 - out_y1,
1638 in_x1, in_y1, in_x2 - in_x1, in_y2 - in_y1,
1642 for( int i = out_x2; i < out_x3; i += in_x3 - in_x2 ) {
1643 if( out_x3 - i > 0 ) {
1644 int w = MIN(in_x3 - in_x2, out_x3 - i);
1645 draw_bitmap(temp_bitmap, 0,
1646 x + i, y + out_y1, w, out_y2 - out_y1,
1647 in_x2, in_y1, w, in_y2 - in_y1,
1653 draw_bitmap(temp_bitmap, 0,
1654 x + out_x3, y + out_y1, out_x4 - out_x3, out_y2 - out_y1,
1655 in_x3, in_y1, in_x4 - in_x3, in_y2 - in_y1,
1659 for( int i = out_y2; i < out_y3; i += in_y3 - in_y2 ) {
1660 if( out_y3 - i > 0 ) {
1661 int h = MIN(in_y3 - in_y2, out_y3 - i);
1662 draw_bitmap(temp_bitmap, 0,
1663 x + out_x1, y + i, out_x2 - out_x1, h,
1664 in_x1, in_y2, in_x2 - in_x1, h,
1669 // Segment 5 * n * n
1670 for( int i = out_y2; i < out_y3; i += in_y3 - in_y2 ) {
1671 if( out_y3 - i > 0 ) {
1672 int h = MIN(in_y3 - in_y2, out_y3 - i);
1674 for( int j = out_x2; j < out_x3; j += in_x3 - in_x2 ) {
1675 int w = MIN(in_x3 - in_x2, out_x3 - j);
1677 draw_bitmap(temp_bitmap, 0,
1686 for( int i = out_y2; i < out_y3; i += in_y_third ) {
1687 if( out_y3 - i > 0 ) {
1688 int h = MIN(in_y_third, out_y3 - i);
1689 draw_bitmap(temp_bitmap, 0,
1690 x + out_x3, y + i, out_x4 - out_x3, h,
1691 in_x3, in_y2, in_x4 - in_x3, h,
1697 draw_bitmap(temp_bitmap, 0,
1698 x + out_x1, y + out_y3, out_x2 - out_x1, out_y4 - out_y3,
1699 in_x1, in_y3, in_x2 - in_x1, in_y4 - in_y3,
1703 for( int i = out_x2; i < out_x3; i += in_x_third ) {
1704 if( out_x3 - i > 0 ) {
1705 int w = MIN(in_x_third, out_x3 - i);
1706 draw_bitmap(temp_bitmap, 0,
1707 x + i, y + out_y3, w, out_y4 - out_y3,
1708 in_x2, in_y3, w, in_y4 - in_y3,
1714 draw_bitmap(temp_bitmap, 0,
1715 x + out_x3, y + out_y3, out_x4 - out_x3, out_y4 - out_y3,
1716 in_x3, in_y3, in_x4 - in_x3, in_y4 - in_y3,