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 void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_Pixmap *pixmap)
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);
48 void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
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);
57 void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
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);
64 void BC_WindowBase::draw_arc(int x, int y, int w, int h,
65 int start_angle, int angle_length, BC_Pixmap *pixmap)
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,
73 void BC_WindowBase::draw_disc(int x, int y, int w, int h, BC_Pixmap *pixmap)
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);
80 void BC_WindowBase::clear_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
83 Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
84 XFillRectangle(top_level->display, xpixmap, top_level->gc, x, y, w, h);
87 void BC_WindowBase::draw_text_line(int x, int y, const char *text, int len,
91 if( get_resources()->use_xft ) {
92 draw_xft_text(x, y, text, len, pixmap);
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();
100 XmbDrawString(top_level->display, xpixmap, fontset,
101 top_level->gc, x, y, text, len);
106 //printf("BC_WindowBase::draw_text 3\n");
107 XDrawString(top_level->display, xpixmap, top_level->gc, x, y, text, len);
110 void BC_WindowBase::draw_text(int x, int y, const char *text, int length,
113 if( length < 0 ) length = strlen(text);
114 //int boldface = top_level->current_font & BOLDFACE;
115 int font = top_level->current_font & 0xff;
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;
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;
134 case '-': image = img7seg[19]; break;
136 case ' ': image = img7seg[18]; break;
139 draw_vframe(image, x, y - image->get_h());
145 if(top_level->get_xft_struct(top_level->current_font)) {
146 draw_xft_text(x, y, text, length, pixmap);
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);
159 XDrawString(top_level->display,
160 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
161 top_level->gc, x, y, &text[j], i-j);
164 y += get_text_height(font);
172 void BC_WindowBase::draw_utf8_text(int x, int y,
173 const char *text, int length, BC_Pixmap *pixmap)
175 if(length < 0) length = strlen(text);
177 if(top_level->get_xft_struct(top_level->current_font))
188 for(int i = 0, j = 0; i <= length; i++)
190 if(text[i] == '\n' || text[i] == 0)
192 if(get_resources()->use_fontset && top_level->get_curr_fontset())
194 XmbDrawString(top_level->display,
195 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
196 top_level->get_curr_fontset(),
205 XDrawString(top_level->display,
206 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
215 y += get_text_height(MEDIUMFONT);
220 void BC_WindowBase::draw_xft_text(int x, int y,
221 const char *text, int length, BC_Pixmap *pixmap, int is_utf8)
224 wchar_t wide_text[l];
225 length = BC_Resources::encode(
226 is_utf8 ? "UTF8" : BC_Resources::encoding, BC_Resources::wide_encoding,
227 (char*)text, length, (char*)wide_text, l*sizeof(wchar_t)) / sizeof(wchar_t);
228 draw_xft_text(x, y, wide_text, length, pixmap);
231 void BC_WindowBase::draw_xft_text(int x, int y,
232 const wchar_t *text, int length, BC_Pixmap *pixmap)
235 const wchar_t *wsp = text, *wep = wsp + length;
237 const wchar_t *wcp = wsp;
238 while( wcp < wep && *wcp != '\n' ) ++wcp;
241 draw_wtext(x, y, wsp, len, pixmap);
242 if( wcp >= wep ) break;
244 dy = get_text_height(top_level->current_font);
250 int BC_WindowBase::wcharpos(const wchar_t *text, XftFont *font, int length,
257 int bpos = charpos[-1];
259 for(int i = 0; i < length; i++)
261 XftTextExtents32(top_level->display,
263 (const FcChar32*)text,
266 charpos[i] = extents.xOff + bpos;
268 return charpos[length - 1] - bpos;
272 XftTextExtents32(top_level->display,
274 (const FcChar32*)text,
281 void BC_WindowBase::draw_wtext(int x, int y,
282 const wchar_t *text, int length, BC_Pixmap *pixmap, int *charpos)
284 if( !get_resources()->use_xft ) {
285 if( !get_font_struct(current_font) ) return;
286 XChar2b xtext[length], *xp = xtext;
287 for( int i=0; i<length; ++i,++xp ) {
288 xp->byte1 = (unsigned char) (text[i] >> 8);
289 xp->byte2 = (unsigned char) (text[i] & 0xff);
291 XDrawString16(top_level->display,
292 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
293 top_level->gc, x, y, xtext, length);
298 const wchar_t *up, *ubp;
301 XftFont *curfont, *nextfont, *altfont, *basefont;
304 length = wcslen(text);
311 color.red = (top_level->current_color & 0xff0000) >> 16;
312 color.red |= color.red << 8;
313 color.green = (top_level->current_color & 0xff00) >> 8;
314 color.green |= color.green << 8;
315 color.blue = (top_level->current_color & 0xff);
316 color.blue |= color.blue << 8;
317 color.alpha = 0xffff;
319 XftColorAllocValue(top_level->display,
325 basefont = top_level->get_xft_struct(top_level->current_font);
327 curfont = nextfont = basefont;
332 for(up = text; up < &text[length]; up++)
334 if(XftCharExists(top_level->display, basefont, *up))
336 else if(altfont && XftCharExists(top_level->display, altfont, *up))
341 XftFontClose(top_level->display, altfont);
343 if( (newpat = BC_Resources::find_similar_font(*up, basefont->pattern)) != 0 ) {
346 FcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE,
348 FcPatternAddDouble(newpat, FC_PIXEL_SIZE, psize);
349 FcPatternDel(newpat, FC_SCALABLE);
350 altfont = XftFontOpenPattern(top_level->display,
361 if(nextfont != curfont)
364 XftDrawString32((XftDraw*)(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw),
369 (const FcChar32*)ubp,
373 cp = &charpos[ubp - text + 1];
375 x += wcharpos(ubp, curfont, l, cp);
383 XftDrawString32((XftDraw*)(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw),
388 (const FcChar32*)ubp,
391 wcharpos(ubp, curfont, up - ubp, &charpos[ubp - text + 1]);
395 XftFontClose(top_level->display, altfont);
397 XftColorFree(top_level->display,
403 void BC_WindowBase::truncate_text(char *result, const char *text, int w)
405 int new_w = get_text_width(current_font, text);
409 const char* separator = "...";
410 int separator_w = get_text_width(current_font, separator);
414 strcpy(result, separator);
418 int text_len = strlen(text);
419 // widen middle gap until it fits
420 for(int i = text_len / 2; i > 0; i--)
422 strncpy(result, text, i);
424 strcat(result, separator);
425 strncat(result, text + text_len - i, i);
426 result[i + strlen(separator) + i] = 0;
427 new_w = get_text_width(current_font, result);
428 //printf("BC_WindowBase::truncate_text %d %d %d %s\n", __LINE__, new_w, w, result);
429 if(new_w < w) return;
433 strcpy(result, separator);
438 strcpy(result, text);
442 void BC_WindowBase::draw_center_text(int x, int y, const char *text, int length)
444 if(length < 0) length = strlen(text);
445 int w = get_text_width(current_font, text, length);
447 draw_text(x, y, text, length);
450 void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
452 // Some X drivers can't draw 0 length lines
453 if(x1 == x2 && y1 == y2)
455 draw_pixel(x1, y1, pixmap);
459 XDrawLine(top_level->display,
460 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
469 void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
471 int npoints = MIN(x->total, y->total);
472 XPoint *points = new XPoint[npoints];
474 for(int i = 0; i < npoints; i++)
476 points[i].x = x->values[i];
477 points[i].y = y->values[i];
480 XDrawLines(top_level->display,
481 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
490 void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
492 int npoints = MIN(x->total, y->total);
493 XPoint *points = new XPoint[npoints];
495 for(int i = 0; i < npoints; i++)
497 points[i].x = x->values[i];
498 points[i].y = y->values[i];
501 XFillPolygon(top_level->display,
502 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
513 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
515 XDrawRectangle(top_level->display,
516 pixmap->opaque_pixmap,
524 void BC_WindowBase::draw_3d_border(int x,
534 top_level->get_resources()->border_shadow2,
535 top_level->get_resources()->border_shadow1,
536 top_level->get_resources()->border_light1,
537 top_level->get_resources()->border_light2);
541 void BC_WindowBase::draw_3d_border(int x,
555 ux = x+w-1; uy = y+h-1;
558 draw_line(x, y, ux, y);
559 draw_line(x, y, x, uy);
561 draw_line(lx, ly, ux - 1, ly);
562 draw_line(lx, ly, lx, uy - 1);
565 draw_line(ux, ly, ux, uy);
566 draw_line(lx, uy, ux, uy);
568 draw_line(x + w, y, x + w, y + h);
569 draw_line(x, y + h, x + w, y + h);
572 void BC_WindowBase::draw_3d_box(int x,
588 ux = x+w-1; uy = y+h-1;
591 draw_box(x, y, w, h, pixmap);
594 draw_line(x, y, ux, y, pixmap);
595 draw_line(x, y, x, uy, pixmap);
597 draw_line(lx, ly, ux - 1, ly, pixmap);
598 draw_line(lx, ly, lx, uy - 1, pixmap);
601 draw_line(ux, ly, ux, uy, pixmap);
602 draw_line(lx, uy, ux, uy, pixmap);
604 draw_line(x + w, y, x + w, y + h, pixmap);
605 draw_line(x, y + h, x + w, y + h, pixmap);
608 void BC_WindowBase::draw_colored_box(int x, int y, int w, int h, int down, int highlighted)
613 draw_3d_box(x, y, w, h,
614 top_level->get_resources()->button_light,
615 top_level->get_resources()->button_highlighted,
616 top_level->get_resources()->button_highlighted,
617 top_level->get_resources()->button_shadow,
620 draw_3d_box(x, y, w, h,
621 top_level->get_resources()->button_light,
622 top_level->get_resources()->button_up,
623 top_level->get_resources()->button_up,
624 top_level->get_resources()->button_shadow,
629 // need highlighting for toggles
631 draw_3d_box(x, y, w, h,
632 top_level->get_resources()->button_shadow,
634 top_level->get_resources()->button_up,
635 top_level->get_resources()->button_up,
636 top_level->get_resources()->button_light);
638 draw_3d_box(x, y, w, h,
639 top_level->get_resources()->button_shadow,
641 top_level->get_resources()->button_down,
642 top_level->get_resources()->button_down,
643 top_level->get_resources()->button_light);
648 void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
650 int left_indent = 20;
654 lx = x + 1; ly = y + 1;
655 ux = x + w - 1; uy = y + h - 1;
658 if(text && text[0] != 0)
661 set_font(MEDIUMFONT);
662 draw_text(x + left_indent, y + get_text_height(MEDIUMFONT) / 2, text);
665 set_color(top_level->get_resources()->button_shadow);
666 draw_line(x, y, x + left_indent - 5, y);
667 draw_line(x, y, x, uy);
668 draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), y, ux, y);
669 draw_line(x, y, x, uy);
670 draw_line(ux, ly, ux, uy);
671 draw_line(lx, uy, ux, uy);
672 set_color(top_level->get_resources()->button_light);
673 draw_line(lx, ly, x + left_indent - 5 - 1, ly);
674 draw_line(lx, ly, lx, uy - 1);
675 draw_line(x + left_indent + 5 + get_text_width(MEDIUMFONT, text), ly, ux - 1, ly);
676 draw_line(lx, ly, lx, uy - 1);
677 draw_line(x + w, y, x + w, y + h);
678 draw_line(x, y + h, x + w, y + h);
681 void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
683 int x1, y1, x2, y2, x3;
686 x1 = x; x2 = x + w / 2; x3 = x + w - 1;
687 y1 = y; y2 = y + h - 1;
689 point[0].x = x2; point[0].y = y2; point[1].x = x3;
690 point[1].y = y1; point[2].x = x1; point[2].y = y1;
692 XFillPolygon(top_level->display,
693 pixmap->opaque_pixmap,
701 void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h,
702 int light1, int light2, int middle, int shadow1, int shadow2)
704 int x1, y1, x2, y2, x3;
707 x1 = x; y1 = y; x2 = x + w / 2;
708 y2 = y + h - 1; x3 = x + w - 1;
711 point[0].x = x2; point[0].y = y1; point[1].x = x3;
712 point[1].y = y2; point[2].x = x1; point[2].y = y2;
715 XFillPolygon(top_level->display,
716 pixmap->opaque_pixmap,
723 // bottom and top right
725 draw_line(x3, y2-1, x1, y2-1);
726 draw_line(x2-1, y1, x3-1, y2);
728 draw_line(x3, y2, x1, y2);
729 draw_line(x2, y1, x3, y2);
733 draw_line(x2+1, y1, x1+1, y2);
735 draw_line(x2, y1, x1, y2);
738 void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h,
739 int light1, int light2, int middle, int shadow1, int shadow2)
741 int x1, y1, x2, y2, x3;
744 x1 = x; x2 = x + w / 2; x3 = x + w - 1;
745 y1 = y; y2 = y + h - 1;
747 point[0].x = x2; point[0].y = y2; point[1].x = x3;
748 point[1].y = y1; point[2].x = x1; point[2].y = y1;
751 XFillPolygon(top_level->display,
752 pixmap->opaque_pixmap,
759 // top and bottom left
761 draw_line(x3-1, y1+1, x1+1, y1+1);
762 draw_line(x1+1, y1, x2+1, y2);
764 draw_line(x3, y1, x1, y1);
765 draw_line(x1, y1, x2, y2);
769 draw_line(x3-1, y1, x2-1, y2);
771 draw_line(x3, y1, x2, y2);
774 void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
775 int light1, int light2, int middle, int shadow1, int shadow2)
777 int x1, y1, x2, y2, y3;
781 y1 = y; x1 = x; y2 = y + h / 2;
782 x2 = x + w - 1; y3 = y + h - 1;
784 point[0].x = x1; point[0].y = y2; point[1].x = x2;
785 point[1].y = y1; point[2].x = x2; point[2].y = y3;
788 XFillPolygon(top_level->display,
789 pixmap->opaque_pixmap,
796 // right and bottom right
798 draw_line(x2-1, y1, x2-1, y3-1);
799 draw_line(x2, y3-1, x1, y2-1);
801 draw_line(x2, y1, x2, y3);
802 draw_line(x2, y3, x1, y2);
806 draw_line(x1, y2, x2, y1);
808 draw_line(x1, y2+1, x2, y1+1);
811 void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h,
812 int light1, int light2, int middle, int shadow1, int shadow2)
814 int x1, y1, x2, y2, y3;
817 y1 = y; y2 = y + h / 2; y3 = y + h - 1;
818 x1 = x; x2 = x + w - 1;
820 point[0].x = x1; point[0].y = y1; point[1].x = x2;
821 point[1].y = y2; point[2].x = x1; point[2].y = y3;
824 XFillPolygon(top_level->display,
825 pixmap->opaque_pixmap,
832 // left and top right
834 draw_line(x1+1, y3, x1+1, y1);
835 draw_line(x1, y1+1, x2, y2+1);
837 draw_line(x1, y3, x1, y1);
838 draw_line(x1, y1, x2, y2);
842 draw_line(x2, y2-1, x1, y3-1);
844 draw_line(x2, y2, x1, y3);
848 void BC_WindowBase::draw_check(int x, int y)
850 const int w = 15, h = 15;
851 draw_line(x + 3, y + h / 2 + 0, x + 6, y + h / 2 + 2);
852 draw_line(x + 3, y + h / 2 + 1, x + 6, y + h / 2 + 3);
853 draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
854 draw_line(x + 3, y + h / 2 + 2, x + 6, y + h / 2 + 4);
855 draw_line(x + 6, y + h / 2 + 2, x + w - 4, y + h / 2 - 3);
856 draw_line(x + 6, y + h / 2 + 3, x + w - 4, y + h / 2 - 2);
857 draw_line(x + 6, y + h / 2 + 4, x + w - 4, y + h / 2 - 1);
860 void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
865 draw_box(x, y, w, h);
869 XSetFillStyle(top_level->display, top_level->gc, FillTiled);
870 // Don't know how slow this is
871 XSetTile(top_level->display, top_level->gc, tile->get_pixmap());
872 XSetTSOrigin(top_level->display, top_level->gc, origin_x, origin_y);
873 draw_box(x, y, w, h);
874 XSetFillStyle(top_level->display, top_level->gc, FillSolid);
878 void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
881 int origin_x, origin_y;
882 XTranslateCoordinates(top_level->display,
891 draw_tiles(parent_window->bg_pixmap,
900 void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window,
909 XLockDisplay(top_level->display);
911 XTranslateCoordinates(top_level->display,
920 XCopyArea(top_level->display,
921 parent_window->pixmap->opaque_pixmap,
922 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
931 XUnlockDisplay(top_level->display);
934 void BC_WindowBase::draw_background(int x, int y, int w, int h)
938 draw_tiles(bg_pixmap, 0, 0, x, y, w, h);
942 clear_box(x, y, w, h);
946 void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap,
959 // Hide cursor if video enabled
960 update_video_cursor();
962 //printf("BC_WindowBase::draw_bitmap 1\n");
963 if(dest_w <= 0 || dest_h <= 0)
965 // Use hardware scaling to canvas dimensions if proper color model.
966 if(bitmap->get_color_model() == BC_YUV420P)
973 dest_w = bitmap->get_w();
974 dest_h = bitmap->get_h();
978 if(src_w <= 0 || src_h <= 0)
980 src_w = bitmap->get_w();
981 src_h = bitmap->get_h();
986 bitmap->write_drawable(win,
1001 bitmap->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1011 //printf("BC_WindowBase::draw_bitmap 2\n");
1015 void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
1017 XDrawPoint(top_level->display,
1018 pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1025 void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap,
1034 pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
1043 void BC_WindowBase::draw_vframe(VFrame *frame,
1054 if(dest_w <= 0) dest_w = frame->get_w() - src_x;
1055 if(dest_h <= 0) dest_h = frame->get_h() - src_y;
1056 if(src_w <= 0) src_w = frame->get_w() - src_x;
1057 if(src_h <= 0) src_h = frame->get_h() - src_y;
1058 CLAMP(src_x, 0, frame->get_w() - 1);
1059 CLAMP(src_y, 0, frame->get_h() - 1);
1060 if(src_x + src_w > frame->get_w()) src_w = frame->get_w() - src_x;
1061 if(src_y + src_h > frame->get_h()) src_h = frame->get_h() - src_y;
1063 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(this,
1069 temp_bitmap->match_params(dest_w,
1074 temp_bitmap->read_frame(frame,
1084 draw_bitmap(temp_bitmap,
1097 void BC_WindowBase::draw_tooltip()
1099 if(tooltip_popup && tooltip_text)
1101 int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
1102 tooltip_popup->set_color(get_resources()->tooltip_bg_color);
1103 tooltip_popup->draw_box(0, 0, w, h);
1104 tooltip_popup->set_color(BLACK);
1105 tooltip_popup->draw_rectangle(0, 0, w, h);
1106 tooltip_popup->set_font(MEDIUMFONT);
1107 tooltip_popup->draw_text(TOOLTIP_MARGIN,
1108 get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN,
1113 void BC_WindowBase::slide_left(int distance)
1117 XCopyArea(top_level->display,
1118 pixmap->opaque_pixmap,
1119 pixmap->opaque_pixmap,
1130 void BC_WindowBase::slide_right(int distance)
1134 XCopyArea(top_level->display,
1135 pixmap->opaque_pixmap,
1136 pixmap->opaque_pixmap,
1147 void BC_WindowBase::slide_up(int distance)
1151 XCopyArea(top_level->display,
1152 pixmap->opaque_pixmap,
1153 pixmap->opaque_pixmap,
1161 set_color(bg_color);
1162 XFillRectangle(top_level->display,
1163 pixmap->opaque_pixmap,
1172 void BC_WindowBase::slide_down(int distance)
1176 XCopyArea(top_level->display,
1177 pixmap->opaque_pixmap,
1178 pixmap->opaque_pixmap,
1186 set_color(bg_color);
1187 XFillRectangle(top_level->display,
1188 pixmap->opaque_pixmap,
1197 // 3 segments in separate pixmaps. Obsolete.
1198 void BC_WindowBase::draw_3segment(int x,
1202 BC_Pixmap *left_image,
1203 BC_Pixmap *mid_image,
1204 BC_Pixmap *right_image,
1207 if(w <= 0 || h <= 0) return;
1208 int left_boundary = left_image->get_w_fixed();
1209 int right_boundary = w - right_image->get_w_fixed();
1210 for(int i = 0; i < w; )
1214 if(i < left_boundary)
1217 if(i < right_boundary)
1220 image = right_image;
1222 int output_w = image->get_w_fixed();
1224 if(i < left_boundary)
1226 if(i + output_w > left_boundary) output_w = left_boundary - i;
1229 if(i < right_boundary)
1231 if(i + output_w > right_boundary) output_w = right_boundary - i;
1234 if(i + output_w > w) output_w = w - i;
1236 image->write_drawable(pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
1247 // 3 segments in separate vframes. Obsolete.
1248 void BC_WindowBase::draw_3segment(int x,
1254 VFrame *right_image,
1257 if(w <= 0 || h <= 0) return;
1258 int left_boundary = left_image->get_w_fixed();
1259 int right_boundary = w - right_image->get_w_fixed();
1262 for(int i = 0; i < w; )
1266 if(i < left_boundary)
1269 if(i < right_boundary)
1272 image = right_image;
1274 int output_w = image->get_w_fixed();
1276 if(i < left_boundary)
1278 if(i + output_w > left_boundary) output_w = left_boundary - i;
1281 if(i < right_boundary)
1283 if(i + output_w > right_boundary) output_w = right_boundary - i;
1286 if(i + output_w > w) output_w = w - i;
1300 if(output_w == 0) break;
1305 // Draw all 3 segments in a single vframe for a changing level
1310 // <------------------------------------------------------------>
1314 // <-------------------------------------------------------------------->
1316 // |-------------------|----------------------|------------------|
1319 void BC_WindowBase::draw_3segmenth(int x,
1334 void BC_WindowBase::draw_3segmenth(int x,
1342 if(total_w <= 0 || w <= 0 || h <= 0) return;
1343 int third_image = image->get_w() / 3;
1344 int half_image = image->get_w() / 2;
1345 //int left_boundary = third_image;
1346 //int right_boundary = total_w - third_image;
1348 int left_in_w = third_image;
1349 int left_out_x = total_x;
1350 int left_out_w = third_image;
1351 int right_in_x = image->get_w() - third_image;
1352 int right_in_w = third_image;
1353 int right_out_x = total_x + total_w - third_image;
1354 int right_out_w = third_image;
1355 int center_out_x = total_x + third_image;
1356 int center_out_w = total_w - third_image * 2;
1357 //int image_x, image_w;
1359 //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",
1360 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1364 left_in_w -= x - left_out_x;
1365 left_out_w -= x - left_out_x;
1366 left_in_x += x - left_out_x;
1367 left_out_x += x - left_out_x;
1370 if(left_out_x + left_out_w > x + w)
1372 left_in_w -= (left_out_x + left_out_w) - (x + w);
1373 left_out_w -= (left_out_x + left_out_w) - (x + w);
1378 right_in_w -= x - right_out_x;
1379 right_out_w -= x - right_out_x;
1380 right_in_x += x - right_out_x;
1381 right_out_x += x - right_out_x;
1384 if(right_out_x + right_out_w > x + w)
1386 right_in_w -= (right_out_x + right_out_w) - (x + w);
1387 right_out_w -= (right_out_x + right_out_w) - (x + w);
1390 if(center_out_x < x)
1392 center_out_w -= x - center_out_x;
1393 center_out_x += x - center_out_x;
1396 if(center_out_x + center_out_w > x + w)
1398 center_out_w -= (center_out_x + center_out_w) - (x + w);
1401 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1406 temp_bitmap->match_params(image->get_w(),
1410 temp_bitmap->read_frame(image,
1417 //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",
1418 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1421 draw_bitmap(temp_bitmap,
1429 -1, // src width and height are meaningless in video_off mode
1436 draw_bitmap(temp_bitmap,
1444 -1, // src width and height are meaningless in video_off mode
1449 for(int pixel = center_out_x;
1450 pixel < center_out_x + center_out_w;
1451 pixel += half_image)
1453 int fragment_w = half_image;
1454 if(fragment_w + pixel > center_out_x + center_out_w)
1455 fragment_w = (center_out_x + center_out_w) - pixel;
1457 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1458 draw_bitmap(temp_bitmap,
1466 -1, // src width and height are meaningless in video_off mode
1479 void BC_WindowBase::draw_3segmenth(int x,
1487 if(w <= 0 || total_w <= 0) return;
1488 if(!src) printf("BC_WindowBase::draw_3segmenth src=0\n");
1489 int quarter_src = src->get_w() / 4;
1490 int half_src = src->get_w() / 2;
1491 //int left_boundary = quarter_src;
1492 //int right_boundary = total_w - quarter_src;
1494 int left_in_w = quarter_src;
1495 int left_out_x = total_x;
1496 int left_out_w = quarter_src;
1497 int right_in_x = src->get_w() - quarter_src;
1498 int right_in_w = quarter_src;
1499 int right_out_x = total_x + total_w - quarter_src;
1500 int right_out_w = quarter_src;
1501 int center_out_x = total_x + quarter_src;
1502 int center_out_w = total_w - quarter_src * 2;
1505 //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",
1506 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1510 left_in_w -= x - left_out_x;
1511 left_out_w -= x - left_out_x;
1512 left_in_x += x - left_out_x;
1513 left_out_x += x - left_out_x;
1516 if(left_out_x + left_out_w > x + w)
1518 left_in_w -= (left_out_x + left_out_w) - (x + w);
1519 left_out_w -= (left_out_x + left_out_w) - (x + w);
1524 right_in_w -= x - right_out_x;
1525 right_out_w -= x - right_out_x;
1526 right_in_x += x - right_out_x;
1527 right_out_x += x - right_out_x;
1530 if(right_out_x + right_out_w > x + w)
1532 right_in_w -= (right_out_x + right_out_w) - (x + w);
1533 right_out_w -= (right_out_x + right_out_w) - (x + w);
1536 if(center_out_x < x)
1538 center_out_w -= x - center_out_x;
1539 center_out_x += x - center_out_x;
1542 if(center_out_x + center_out_w > x + w)
1544 center_out_w -= (center_out_x + center_out_w) - (x + w);
1548 //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",
1549 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1574 for(int pixel = center_out_x;
1575 pixel < center_out_x + center_out_w;
1578 int fragment_w = half_src;
1579 if(fragment_w + pixel > center_out_x + center_out_w)
1580 fragment_w = (center_out_x + center_out_w) - pixel;
1582 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1596 void BC_WindowBase::draw_3segmenth(int x,
1603 int third_image = src->get_w() / 3;
1604 int half_output = w / 2;
1605 //int left_boundary = third_image;
1606 //int right_boundary = w - third_image;
1608 int left_in_w = third_image;
1610 int left_out_w = third_image;
1611 int right_in_x = src->get_w() - third_image;
1612 int right_in_w = third_image;
1613 int right_out_x = x + w - third_image;
1614 int right_out_w = third_image;
1615 //int image_x, image_w;
1617 //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",
1618 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1620 if(left_out_w > half_output)
1622 left_in_w -= left_out_w - half_output;
1623 left_out_w -= left_out_w - half_output;
1626 if(right_out_x < x + half_output)
1628 right_in_w -= x + half_output - right_out_x;
1629 right_out_w -= x + half_output - right_out_x;
1630 right_in_x += x + half_output - right_out_x;
1631 right_out_x += x + half_output - right_out_x;
1634 //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",
1635 // left_out_x, left_out_w, center_out_x, center_out_w, right_out_x, right_out_w);
1660 for(int pixel = left_out_x + left_out_w;
1661 pixel < right_out_x;
1662 pixel += third_image)
1664 int fragment_w = third_image;
1665 if(fragment_w + pixel > right_out_x)
1666 fragment_w = right_out_x - pixel;
1668 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1687 void BC_WindowBase::draw_3segmentv(int x,
1694 int third_image = src->get_h() / 3;
1695 int half_output = h / 2;
1696 //int left_boundary = third_image;
1697 //int right_boundary = h - third_image;
1699 int left_in_h = third_image;
1701 int left_out_h = third_image;
1702 int right_in_y = src->get_h() - third_image;
1703 int right_in_h = third_image;
1704 int right_out_y = y + h - third_image;
1705 int right_out_h = third_image;
1706 //int image_y, image_h;
1709 if(left_out_h > half_output)
1711 left_in_h -= left_out_h - half_output;
1712 left_out_h -= left_out_h - half_output;
1715 if(right_out_y < y + half_output)
1717 right_in_h -= y + half_output - right_out_y;
1718 right_out_h -= y + half_output - right_out_y;
1719 right_in_y += y + half_output - right_out_y;
1720 right_out_y += y + half_output - right_out_y;
1724 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
1729 temp_bitmap->match_params(src->get_w(),
1733 temp_bitmap->read_frame(src,
1742 draw_bitmap(temp_bitmap,
1757 draw_bitmap(temp_bitmap,
1770 for(int pixel = left_out_y + left_out_h;
1771 pixel < right_out_y;
1772 pixel += third_image)
1774 int fragment_h = third_image;
1775 if(fragment_h + pixel > right_out_y)
1776 fragment_h = right_out_y - pixel;
1778 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1779 draw_bitmap(temp_bitmap,
1793 void BC_WindowBase::draw_3segmentv(int x,
1800 int third_image = src->get_h() / 3;
1801 int half_output = h / 2;
1802 //int left_boundary = third_image;
1803 //int right_boundary = h - third_image;
1805 int left_in_h = third_image;
1807 int left_out_h = third_image;
1808 int right_in_y = src->get_h() - third_image;
1809 int right_in_h = third_image;
1810 int right_out_y = y + h - third_image;
1811 int right_out_h = third_image;
1812 //int image_y, image_h;
1815 if(left_out_h > half_output)
1817 left_in_h -= left_out_h - half_output;
1818 left_out_h -= left_out_h - half_output;
1821 if(right_out_y < y + half_output)
1823 right_in_h -= y + half_output - right_out_y;
1824 right_out_h -= y + half_output - right_out_y;
1825 right_in_y += y + half_output - right_out_y;
1826 right_out_y += y + half_output - right_out_y;
1853 for(int pixel = left_out_y + left_out_h;
1854 pixel < right_out_y;
1855 pixel += third_image)
1857 int fragment_h = third_image;
1858 if(fragment_h + pixel > right_out_y)
1859 fragment_h = right_out_y - pixel;
1861 //printf("BC_WindowBase::draw_3segment 2 pixel=%d fragment_w=%d\n", pixel, fragment_w);
1874 void BC_WindowBase::draw_9segment(int x,
1881 if(w <= 0 || h <= 0) return;
1883 int in_x_third = src->get_w() / 3;
1884 int in_y_third = src->get_h() / 3;
1885 int out_x_half = w / 2;
1886 int out_y_half = h / 2;
1892 int in_x2 = MIN(in_x_third, out_x_half);
1893 int in_y2 = MIN(in_y_third, out_y_half);
1897 int out_x3 = MAX(w - out_x_half, w - in_x_third);
1899 int in_x3 = src->get_w() - (out_x4 - out_x3);
1900 //int in_x4 = src->get_w();
1902 int out_y3 = MAX(h - out_y_half, h - in_y_third);
1904 int in_y3 = src->get_h() - (out_y4 - out_y3);
1905 //int in_y4 = src->get_h();
1919 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
1923 int w = MIN(in_x3 - in_x2, out_x3 - i);
1952 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1956 int h = MIN(in_y3 - in_y2, out_y3 - i);
1969 // Segment 5 * n * n
1970 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2 /* in_y_third */)
1974 int h = MIN(in_y3 - in_y2 /* in_y_third */, out_y3 - i);
1977 for(int j = out_x2; j < out_x3; j += in_x3 - in_x2 /* in_x_third */)
1979 int w = MIN(in_x3 - in_x2 /* in_x_third */, out_x3 - j);
1994 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
1998 int h = MIN(in_y3 - in_y2, out_y3 - i);
2025 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
2029 int w = MIN(in_x3 - in_y2, out_x3 - i);
2055 void BC_WindowBase::draw_9segment(int x,
2062 if(w <= 0 || h <= 0) return;
2064 int in_x_third = src->get_w() / 3;
2065 int in_y_third = src->get_h() / 3;
2066 int out_x_half = w / 2;
2067 int out_y_half = h / 2;
2073 int in_x2 = MIN(in_x_third, out_x_half);
2074 int in_y2 = MIN(in_y_third, out_y_half);
2078 int out_x3 = MAX(w - out_x_half, w - in_x_third);
2080 int in_x3 = src->get_w() - (out_x4 - out_x3);
2081 int in_x4 = src->get_w();
2083 int out_y3 = MAX(h - out_y_half, h - in_y_third);
2085 int in_y3 = src->get_h() - (out_y4 - out_y3);
2086 int in_y4 = src->get_h();
2088 //printf("PFCFrame::draw_9segment 1 %d %d %d %d\n", out_x1, out_x2, out_x3, out_x4);
2089 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_x1, in_x2, in_x3, in_x4);
2090 //printf("PFCFrame::draw_9segment 2 %d %d %d %d\n", in_y1, in_y2, in_y3, in_y4);
2092 if(!temp_bitmap) temp_bitmap = new BC_Bitmap(top_level,
2097 temp_bitmap->match_params(src->get_w(),
2101 temp_bitmap->read_frame(src,
2108 draw_bitmap(temp_bitmap,
2122 for(int i = out_x2; i < out_x3; i += in_x3 - in_x2)
2126 int w = MIN(in_x3 - in_x2, out_x3 - i);
2127 draw_bitmap(temp_bitmap,
2146 draw_bitmap(temp_bitmap,
2161 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
2165 int h = MIN(in_y3 - in_y2, out_y3 - i);
2166 draw_bitmap(temp_bitmap,
2181 // Segment 5 * n * n
2182 for(int i = out_y2; i < out_y3; i += in_y3 - in_y2)
2186 int h = MIN(in_y3 - in_y2, out_y3 - i);
2189 for(int j = out_x2; j < out_x3; j += in_x3 - in_x2)
2191 int w = MIN(in_x3 - in_x2, out_x3 - j);
2193 draw_bitmap(temp_bitmap,
2209 for(int i = out_y2; i < out_y3; i += in_y_third)
2213 int h = MIN(in_y_third, out_y3 - i);
2214 draw_bitmap(temp_bitmap,
2232 draw_bitmap(temp_bitmap,
2246 for(int i = out_x2; i < out_x3; i += in_x_third)
2250 int w = MIN(in_x_third, out_x3 - i);
2251 draw_bitmap(temp_bitmap,
2268 draw_bitmap(temp_bitmap,