olaf neophyte and de.po updates, valgrind tweaks, delete green lady, inkscape dpi=96
[goodguy/history.git] / cinelerra-5.1 / guicast / bcwindowdraw.C
index e95b040260e2b7bb1e7927021697bd070e9e6dfe..c81c36963223fa2b91e6ef3faeaaeff3ba71386e 100644 (file)
 #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,
@@ -46,7 +48,7 @@ void BC_WindowBase::copy_area(int x1, int y1, int x2, int y2, int w, int h, BC_P
 
 
 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,
@@ -55,7 +57,7 @@ void BC_WindowBase::draw_box(int x, int y, int w, int h, BC_Pixmap *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);
@@ -63,7 +65,7 @@ void BC_WindowBase::draw_circle(int x, int y, int w, int h, BC_Pixmap *pixmap)
 
 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,
@@ -71,14 +73,14 @@ void BC_WindowBase::draw_arc(int x, int y, int w, int h,
 }
 
 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);
@@ -93,6 +95,7 @@ void BC_WindowBase::draw_text_line(int x, int y, const char *text, int len,
                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();
@@ -146,7 +149,7 @@ void BC_WindowBase::draw_text(int x, int y, const char *text, int length,
                        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()) {
@@ -183,7 +186,7 @@ void BC_WindowBase::draw_utf8_text(int x, int y,
                        1);
                return;
        }
-
+ BT
        for(int i = 0, j = 0; i <= length; i++)
        {
                if(text[i] == '\n' || text[i] == 0)
@@ -232,54 +235,24 @@ void BC_WindowBase::draw_xft_text(int x, int y,
 {
        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);
@@ -289,138 +262,134 @@ void BC_WindowBase::xft_draw_string(XftColor *xft_color, XftFont *xft_font,
        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)
@@ -471,7 +440,7 @@ void BC_WindowBase::draw_center_text(int x, int y, const char *text, int length)
 }
 
 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)
        {
@@ -490,7 +459,7 @@ void BC_WindowBase::draw_line(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap)
 }
 
 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];
 
@@ -511,7 +480,7 @@ void BC_WindowBase::draw_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap
 }
 
 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];
 
@@ -534,7 +503,7 @@ void BC_WindowBase::fill_polygon(ArrayList<int> *x, ArrayList<int> *y, BC_Pixmap
 
 
 void BC_WindowBase::draw_rectangle(int x, int y, int w, int h)
-{
+{ BT
        XDrawRectangle(top_level->display,
                pixmap->opaque_pixmap,
                top_level->gc,
@@ -702,7 +671,7 @@ void BC_WindowBase::draw_border(char *text, int x, int y, int w, int h)
 }
 
 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];
 
@@ -723,7 +692,7 @@ void BC_WindowBase::draw_triangle_down_flat(int x, int y, int w, int h)
 
 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];
 
@@ -796,7 +765,7 @@ void BC_WindowBase::draw_triangle_down(int x, int y, int w, int h,
 
 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];
 
@@ -833,7 +802,7 @@ void BC_WindowBase::draw_triangle_left(int x, int y, int w, int h,
 
 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];
 
@@ -881,7 +850,7 @@ void BC_WindowBase::draw_check(int x, int y)
 }
 
 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);
@@ -899,7 +868,7 @@ void BC_WindowBase::draw_tiles(BC_Pixmap *tile, int origin_x, int origin_y, int
 }
 
 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,
@@ -926,7 +895,7 @@ void BC_WindowBase::draw_top_background(BC_WindowBase *parent_window,
        int w,
        int h,
        BC_Pixmap *pixmap)
-{
+{ BT
        Window tempwin;
        int top_x, top_y;
        XLockDisplay(top_level->display);
@@ -977,12 +946,11 @@ void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap,
        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.
@@ -1036,7 +1004,7 @@ void BC_WindowBase::draw_bitmap(BC_Bitmap *bitmap,
 
 
 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,
@@ -1053,7 +1021,7 @@ void BC_WindowBase::draw_pixmap(BC_Pixmap *pixmap,
        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,
@@ -1117,9 +1085,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);
@@ -1129,12 +1099,12 @@ 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);
        }
 }
 
 void BC_WindowBase::slide_left(int distance)
-{
+{ BT
        if(distance < w)
        {
                XCopyArea(top_level->display,
@@ -1151,7 +1121,7 @@ void BC_WindowBase::slide_left(int distance)
 }
 
 void BC_WindowBase::slide_right(int distance)
-{
+{ BT
        if(distance < w)
        {
                XCopyArea(top_level->display,
@@ -1168,7 +1138,7 @@ void BC_WindowBase::slide_right(int distance)
 }
 
 void BC_WindowBase::slide_up(int distance)
-{
+{ BT
        if(distance < h)
        {
                XCopyArea(top_level->display,
@@ -1193,7 +1163,7 @@ void BC_WindowBase::slide_up(int distance)
 }
 
 void BC_WindowBase::slide_down(int distance)
-{
+{ BT
        if(distance < h)
        {
                XCopyArea(top_level->display,