X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowdraw.C;h=c5d904ea2b1b58f6c2afadcf7498d09bc9c10d4e;hb=faf9f1da60357505e88f5be80c0256a64bf2d650;hp=635679ea43a7670e607bd0fddedbd069ea0408c9;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/guicast/bcwindowdraw.C b/cinelerra-5.1/guicast/bcwindowdraw.C index 635679ea..c5d904ea 100644 --- a/cinelerra-5.1/guicast/bcwindowdraw.C +++ b/cinelerra-5.1/guicast/bcwindowdraw.C @@ -216,7 +216,7 @@ void BC_WindowBase::draw_utf8_text(int x, int y, } } -void BC_WindowBase::draw_xft_text(int x, int y, +void BC_WindowBase::draw_xft_text(int x, int y, const char *text, int length, BC_Pixmap *pixmap, int is_utf8) { int l = length + 1; @@ -246,42 +246,120 @@ void BC_WindowBase::draw_xft_text(int x, int y, } } -int BC_WindowBase::wcharpos(const wchar_t *text, XftFont *font, int length, - int *charpos) +void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font, + int x, int y, const FcChar32 *fc, int len, BC_Pixmap *pixmap) { - XGlyphInfo extents; + Pixmap draw_pixmap = 0; + XftDraw *xft_draw = (XftDraw *) + (pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw); + int src_x = x, src_y = y, src_w = 0, src_h = 0; + XGCValues values; + XGetGCValues(top_level->display, top_level->gc, GCFunction, &values); + if( values.function != GXcopy ) { + XSetFunction(top_level->display, top_level->gc, GXcopy); + XGlyphInfo 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, + 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); + 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); + } +} - if(charpos) - { - int bpos = charpos[-1]; +int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length) +{ + if( length < 0 ) + length = wcslen(text); + if( !length ) return 0; - for(int i = 0; i < length; i++) - { - XftTextExtents32(top_level->display, - font, - (const FcChar32*)text, - i + 1, - &extents); - charpos[i] = extents.xOff + bpos; + if( !get_resources()->use_xft ) { + if( !get_font_struct(font) ) return 0; + XChar2b xtext[length], *xp = xtext; + for( int i=0; ibyte1 = (unsigned char) (text[i] >> 8); + xp->byte2 = (unsigned char) (text[i] & 0xff); } - return charpos[length - 1] - bpos; + return XTextWidth16(get_font_struct(font), xtext, length); } - else - { - XftTextExtents32(top_level->display, - font, - (const FcChar32*)text, - length, - &extents); - return extents.xOff; + int x = 0; +#ifdef HAVE_XFT + 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; + } + } + 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 ) { + XGlyphInfo extents; + XftTextExtents32(top_level->display, curfont, + (const FcChar32*)ubp, up-ubp, &extents); + x += extents.xOff; + } + ubp = up; curfont = xft_font; + } + ++up; } + + if( curfont && up > ubp ) { + XGlyphInfo extents; + XftTextExtents32(top_level->display, curfont, + (const FcChar32*)ubp, up-ubp, &extents); + x += extents.xOff; + } + + if( altfont ) + XftFontClose(top_level->display, altfont); +#endif + return x; } void BC_WindowBase::draw_wtext(int x, int y, - const wchar_t *text, int length, BC_Pixmap *pixmap, int *charpos) + const wchar_t *text, int length, BC_Pixmap *pixmap) { + if( length < 0 ) + length = wcslen(text); + if( !length ) return; + + int font = top_level->current_font; if( !get_resources()->use_xft ) { - if( !get_font_struct(current_font) ) return; + if( !get_font_struct(font) ) return; XChar2b xtext[length], *xp = xtext; for( int i=0; ibyte1 = (unsigned char) (text[i] >> 8); @@ -292,21 +370,9 @@ void BC_WindowBase::draw_wtext(int x, int y, top_level->gc, x, y, xtext, length); return; } - 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; +#ifdef HAVE_XFT + XRenderColor color; color.red = (top_level->current_color & 0xff0000) >> 16; color.red |= color.red << 8; color.green = (top_level->current_color & 0xff00) >> 8; @@ -315,88 +381,62 @@ void BC_WindowBase::draw_wtext(int x, int y, 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) + XftColor xft_color; + XftColorAllocValue(top_level->display, top_level->vis, top_level->cmap, + &color, &xft_color); + + 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); - - 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 - { altfont = 0; - nextfont = basefont; } } - if(nextfont != curfont) - { - l = up - ubp; - XftDrawString32((XftDraw*)(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw), - &xft_color, - curfont, - x, - y, - (const FcChar32*)ubp, - l); - - 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 ) { + 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) - { - XftDrawString32((XftDraw*)(pixmap ? pixmap->opaque_xft_draw : this->pixmap->opaque_xft_draw), - &xft_color, - curfont, - x, - y, - (const FcChar32*)ubp, - up - ubp); - if(charpos) - wcharpos(ubp, curfont, up - ubp, &charpos[ubp - text + 1]); + if( curfont && up > ubp ) { + xft_draw_string(&xft_color, curfont, x, y, + (const FcChar32*)ubp, up-ubp, pixmap); } - if(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 } void BC_WindowBase::truncate_text(char *result, const char *text, int w) @@ -1093,9 +1133,11 @@ void BC_WindowBase::draw_vframe(VFrame *frame, 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); @@ -1105,7 +1147,7 @@ void BC_WindowBase::draw_tooltip() tooltip_popup->set_font(MEDIUMFONT); tooltip_popup->draw_text(TOOLTIP_MARGIN, get_text_ascent(MEDIUMFONT) + TOOLTIP_MARGIN, - tooltip_text); + text); } }