#include "bctimer.h"
#include "bcwindowbase.h"
#include "clip.h"
-#include "colors.h"
+#include "bccolors.h"
+#include "bctrace.h"
#include "cursors.h"
#include "fonts.h"
#include "vframe.h"
#include <string.h>
#include <wchar.h>
#include <ft2build.h>
+#include "workarounds.h"
void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_Pixmap *pixmap)
-{
+{ BT
XCopyArea(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
-{
+{ BT
//if(x == 0) printf("BC_WindowBase::draw_box %d %d %d %d\n", x, y, w, h);
XFillRectangle(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
-{
+{ BT
XDrawArc(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
void BC_WindowBase::draw_arc(int x, int y, int w, int h,
int start_angle, int angle_length, BC_Pixmap *pixmap)
-{
+{ BT
XDrawArc(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
top_level->gc, x, y, (w - 1), (h - 2), start_angle * 64,
}
void BC_WindowBase::draw_disc(int x, int y, int w, int h, BC_Pixmap *pixmap)
-{
+{ BT
XFillArc(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
top_level->gc, x, y, (w - 1), (h - 2), 0 * 64, 360 * 64);
}
void BC_WindowBase::clear_box(int x, int y, int w, int h, BC_Pixmap *pixmap)
-{
+{ BT
set_color(bg_color);
Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
XFillRectangle(top_level->display, xpixmap, top_level->gc, x, y, w, h);
return;
}
#endif
+ BT
Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
if( get_resources()->use_fontset ) {
XFontSet fontset = top_level->get_curr_fontset();
draw_xft_text(x, y, text, length, pixmap);
return;
}
-
+ BT
for(int i = 0, j = 0; i <= length; i++) {
if(text[i] == '\n' || text[i] == 0) {
if(get_resources()->use_fontset && top_level->get_curr_fontset()) {
1);
return;
}
-
+ BT
for(int i = 0, j = 0; i <= length; i++)
{
if(text[i] == '\n' || text[i] == 0)
{
int dy = -1;
const wchar_t *wsp = text, *wep = wsp + length;
+ int font = top_level->current_font;
while( wsp < wep ) {
const wchar_t *wcp = wsp;
while( wcp < wep && *wcp != '\n' ) ++wcp;
int len = wcp - wsp;
if( len > 0 )
- draw_wtext(x, y, wsp, len, pixmap);
+ draw_single_text(1, font, x, y, wsp, len, pixmap);
if( wcp >= wep ) break;
if( dy < 0 )
- dy = get_text_height(top_level->current_font);
+ dy = get_text_height(font);
y += dy;
wsp = wcp + 1;
}
}
-int BC_WindowBase::wcharpos(const wchar_t *text, XftFont *font, int length,
- int *charpos)
-{
- XGlyphInfo extents;
-
- if(charpos)
- {
- int bpos = charpos[-1];
-
- for(int i = 0; i < length; i++)
- {
- XftTextExtents32(top_level->display,
- font,
- (const FcChar32*)text,
- i + 1,
- &extents);
- charpos[i] = extents.xOff + bpos;
- }
- return charpos[length - 1] - bpos;
- }
- else
- {
- XftTextExtents32(top_level->display,
- font,
- (const FcChar32*)text,
- length,
- &extents);
- return extents.xOff;
- }
-}
-
void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap)
-{
+{ BT
Pixmap draw_pixmap = 0;
XftDraw *xft_draw = (XftDraw *)
(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw);
if( values.function != GXcopy ) {
XSetFunction(top_level->display, top_level->gc, GXcopy);
XGlyphInfo info;
- XftTextExtents32(top_level->display, xft_font, fc, len, &info);
+ xftTextExtents32(top_level->display, xft_font, fc, len, &info);
src_w = info.width; src_h = info.height;
draw_pixmap = XCreatePixmap(top_level->display, top_level->win,
src_w, src_h, top_level->default_depth);
int color = get_color(); set_color(0);
XFillRectangle(top_level->display, draw_pixmap, top_level->gc, 0, 0, src_w, src_h);
set_color(color);
- xft_draw = XftDrawCreate(top_level->display, draw_pixmap,
+ xft_draw = xftDrawCreate(top_level->display, draw_pixmap,
top_level->vis, top_level->cmap);
src_x = info.x; src_y = info.y;
}
- XftDrawString32(xft_draw, xft_color, xft_font, src_x, src_y, fc, len);
+ xftDrawString32(xft_draw, xft_color, xft_font, src_x, src_y, fc, len);
if( values.function != GXcopy ) {
XSetFunction(top_level->display, top_level->gc, values.function);
Pixmap xpixmap = pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap;
XCopyArea(top_level->display, draw_pixmap, xpixmap,
top_level->gc, 0, 0, src_w, src_h, x, y);
XFreePixmap(top_level->display, draw_pixmap);
- XftDrawDestroy(xft_draw);
+ xftDrawDestroy(xft_draw);
}
}
-void BC_WindowBase::draw_wtext(int x, int y,
- const wchar_t *text, int length, BC_Pixmap *pixmap, int *charpos)
+int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
{
+ return draw_single_text(0, font, 0,0, text, length);
+}
+
+int BC_WindowBase::draw_single_text(int draw, int font,
+ int x, int y, const wchar_t *text, int length, BC_Pixmap *pixmap)
+{
+ if( length < 0 )
+ length = wcslen(text);
+ if( !length ) return 0;
+
if( !get_resources()->use_xft ) {
- if( !get_font_struct(current_font) ) return;
+ BT
+ if( !get_font_struct(font) ) return 0;
XChar2b xtext[length], *xp = xtext;
for( int i=0; i<length; ++i,++xp ) {
xp->byte1 = (unsigned char) (text[i] >> 8);
xp->byte2 = (unsigned char) (text[i] & 0xff);
}
- XDrawString16(top_level->display,
- pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
- top_level->gc, x, y, xtext, length);
- return;
+ if( draw ) {
+ XDrawString16(top_level->display,
+ pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
+ top_level->gc, x, y, xtext, length);
+ }
+ return XTextWidth16(get_font_struct(font), xtext, length);
}
- XRenderColor color;
- XftColor xft_color;
- const wchar_t *up, *ubp;
- int l, *cp;
- FcPattern *newpat;
- XftFont *curfont, *nextfont, *altfont, *basefont;
-
- if(length < 0)
- length = wcslen(text);
- if(charpos)
- charpos[0] = 0;
- if(!length)
- return;
-
- color.red = (top_level->current_color & 0xff0000) >> 16;
- color.red |= color.red << 8;
- color.green = (top_level->current_color & 0xff00) >> 8;
- color.green |= color.green << 8;
- color.blue = (top_level->current_color & 0xff);
- color.blue |= color.blue << 8;
- color.alpha = 0xffff;
-
- XftColorAllocValue(top_level->display,
- top_level->vis,
- top_level->cmap,
- &color,
- &xft_color);
-
- basefont = top_level->get_xft_struct(top_level->current_font);
-
- curfont = nextfont = basefont;
- altfont = 0;
- cp = 0;
- ubp = text;
-
- for(up = text; up < &text[length]; up++)
- {
- if(XftCharExists(top_level->display, basefont, *up))
- nextfont = basefont;
- else if(altfont && XftCharExists(top_level->display, altfont, *up))
- nextfont = altfont;
- else
- {
- if(altfont)
- XftFontClose(top_level->display, altfont);
-
- if( (newpat = BC_Resources::find_similar_font(*up, basefont->pattern)) != 0 ) {
- double psize;
-
- FcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE,
- 0, &psize);
- FcPatternAddDouble(newpat, FC_PIXEL_SIZE, psize);
- FcPatternDel(newpat, FC_SCALABLE);
- altfont = XftFontOpenPattern(top_level->display,
- newpat);
- if(altfont)
- nextfont = altfont;
- }
- else
- {
+#ifdef HAVE_XFT
+ XftColor xft_color;
+ if( draw ) {
+ XRenderColor color;
+ color.red = (top_level->current_color & 0xff0000) >> 16;
+ color.red |= color.red << 8;
+ color.green = (top_level->current_color & 0xff00) >> 8;
+ color.green |= color.green << 8;
+ color.blue = (top_level->current_color & 0xff);
+ color.blue |= color.blue << 8;
+ color.alpha = 0xffff;
+
+ xftColorAllocValue(top_level->display, top_level->vis, top_level->cmap,
+ &color, &xft_color);
+ }
+
+ int x0 = x;
+ XftFont *basefont = top_level->get_xft_struct(font);
+ XftFont *curfont = 0, *altfont = 0;
+ const wchar_t *up = text, *ubp = up, *uep = ubp + length;
+
+ while( up < uep ) {
+ XftFont *xft_font = 0;
+ if( xftCharExists(top_level->display, basefont, *up) )
+ xft_font = basefont;
+ else if( altfont ) {
+ if( xftCharExists(top_level->display, altfont, *up))
+ xft_font = altfont;
+ else {
+ xftFontClose(top_level->display, altfont);
altfont = 0;
- nextfont = basefont;
}
}
- if(nextfont != curfont)
- {
- l = up - ubp;
- xft_draw_string(&xft_color, curfont, x, y,
- (const FcChar32*)ubp, l, pixmap);
-
- if(charpos)
- cp = &charpos[ubp - text + 1];
-
- x += wcharpos(ubp, curfont, l, cp);
- ubp = up;
- curfont = nextfont;
+ if( !xft_font ) {
+ FcPattern *pattern = BC_Resources::find_similar_font(*up, basefont->pattern);
+ if( pattern != 0 ) {
+ double psize = 0;
+ fcPatternGetDouble(basefont->pattern, FC_PIXEL_SIZE, 0, &psize);
+ fcPatternAddDouble(pattern, FC_PIXEL_SIZE, psize);
+ fcPatternDel(pattern, FC_SCALABLE);
+ xft_font = altfont = xftFontOpenPattern(top_level->display, pattern);
+ }
}
+ if( !xft_font )
+ xft_font = basefont;
+ if( xft_font != curfont ) {
+ if( curfont && up > ubp ) {
+ if( draw ) {
+ xft_draw_string(&xft_color, curfont, x, y,
+ (const FcChar32*)ubp, up-ubp, pixmap);
+ }
+ XGlyphInfo extents;
+ xftTextExtents32(top_level->display, curfont,
+ (const FcChar32*)ubp, up-ubp, &extents);
+ x += extents.xOff;
+ }
+ ubp = up; curfont = xft_font;
+ }
+ ++up;
}
- if(up > ubp)
- {
- xft_draw_string(&xft_color, curfont, x, y,
- (const FcChar32*)ubp, up - ubp, pixmap);
- if(charpos)
- wcharpos(ubp, curfont, up - ubp, &charpos[ubp - text + 1]);
+ if( curfont && up > ubp ) {
+ if( draw ) {
+ xft_draw_string(&xft_color, curfont, x, y,
+ (const FcChar32*)ubp, up-ubp, pixmap);
+ }
+ XGlyphInfo extents;
+ xftTextExtents32(top_level->display, curfont,
+ (const FcChar32*)ubp, up-ubp, &extents);
+ x += extents.xOff;
}
- if(altfont)
- XftFontClose(top_level->display, altfont);
+ if( altfont )
+ xftFontClose(top_level->display, altfont);
- XftColorFree(top_level->display,
- top_level->vis,
- top_level->cmap,
- &xft_color);
+ xftColorFree(top_level->display, top_level->vis, top_level->cmap, &xft_color);
+#endif
+ return x - x0;
}
void BC_WindowBase::truncate_text(char *result, const char *text, int w)
}
void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
-{
+{ BT
// Some X drivers can't draw 0 length lines
if(x1 == x2 && y1 == y2)
{
}
void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
-{
+{ BT
int npoints = MIN(x->total, y->total);
XPoint *points = new XPoint[npoints];
}
void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap *pixmap)
-{
+{ BT
int npoints = MIN(x->total, y->total);
XPoint *points = new XPoint[npoints];
void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
-{
+{ BT
XDrawRectangle(top_level->display,
pixmap->opaque_pixmap,
top_level->gc,
}
void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
-{
+{ BT
int x1, y1, x2, y2, x3;
XPoint point[3];
void BC_WindowBase::draw_triangle_up(int x, int y, int w, int h,
int light1, int light2, int middle, int shadow1, int shadow2)
-{
+{ BT
int x1, y1, x2, y2, x3;
XPoint point[3];
void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
int light1, int light2, int middle, int shadow1, int shadow2)
-{
+{ BT
int x1, y1, x2, y2, y3;
XPoint point[3];
void BC_WindowBase::draw_triangle_right(int x, int y, int w, int h,
int light1, int light2, int middle, int shadow1, int shadow2)
-{
+{ BT
int x1, y1, x2, y2, y3;
XPoint point[3];
}
void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int x, int y, int w, int h)
-{
+{ BT
if(!tile)
{
set_color(bg_color);
}
void BC_WindowBase::draw_top_tiles(BC_WindowBase *parent_window, int x, int y, int w, int h)
-{
+{ BT
Window tempwin;
int origin_x, origin_y;
XTranslateCoordinates(top_level->display,
int w,
int h,
BC_Pixmap *pixmap)
-{
+{ BT
Window tempwin;
int top_x, top_y;
XLockDisplay(top_level->display);
int src_w,
int src_h,
BC_Pixmap *pixmap)
-{
-
+{ BT
// Hide cursor if video enabled
update_video_cursor();
-//printf("BC_WindowBase::draw_bitmap 1\n");
+//printf("BC_WindowBase::draw_bitmap %d dest_y=%d\n", __LINE__, dest_y);
if(dest_w <= 0 || dest_h <= 0)
{
// Use hardware scaling to canvas dimensions if proper color model.
void BC_WindowBase::draw_pixel(int x, int y, BC_Pixmap *pixmap)
-{
+{ BT
XDrawPoint(top_level->display,
pixmap ? pixmap->opaque_pixmap : this->pixmap->opaque_pixmap,
top_level->gc,
int src_x,
int src_y,
BC_Pixmap *dst)
-{
+{ BT
pixmap->write_drawable(dst ? dst->opaque_pixmap : this->pixmap->opaque_pixmap,
dest_x,
dest_y,
pixmap);
}
-void BC_WindowBase::draw_tooltip()
+void BC_WindowBase::draw_tooltip(const char *text)
{
- if(tooltip_popup && tooltip_text)
+ if( !text )
+ text = tooltip_text;
+ if(tooltip_popup && text)
{
int w = tooltip_popup->get_w(), h = tooltip_popup->get_h();
tooltip_popup->set_color(get_resources()->tooltip_bg_color);
tooltip_popup->set_font(MEDIUMFONT);
tooltip_popup->draw_text(TOOLTIP_MARGIN,
get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN,
- tooltip_text);
+ text);
}
}
void BC_WindowBase::slide_left(int distance)
-{
+{ BT
if(distance < w)
{
XCopyArea(top_level->display,
}
void BC_WindowBase::slide_right(int distance)
-{
+{ BT
if(distance < w)
{
XCopyArea(top_level->display,
}
void BC_WindowBase::slide_up(int distance)
-{
+{ BT
if(distance < h)
{
XCopyArea(top_level->display,
}
void BC_WindowBase::slide_down(int distance)
-{
+{ BT
if(distance < h)
{
XCopyArea(top_level->display,