2014-07-20 50 views
0

我正在嘗試爲我的應用程序使用XFT,但第二次崩潰時我嘗試用新顯示器繪製文本連接在同一個進程內。以下是我的用例的簡化版本。當在同一個應用程序進程中使用XFT字體第二次繪製文本時發生崩潰

while true 
do 
    OpenDisplay 
    LoadFont 
    Draw Text 
    Close Font 
    Close Display 
end 

我在幾個論壇,XCloseDisplay也將關閉字體閱讀,但我注意到內存泄漏,當我試圖與多種字體加載。

我試着調試的問題,這些都是我的觀察,

  1. 評論XftDrawText,崩潰消失
  2. 評論XftFontClose,崩潰消失,但泄漏內存

下面是代碼,我用於重現這一點。任何幫助將不勝感激。

#include <X11/Xlib.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <cstring> 
#include <iostream> 
#include <X11/Xft/Xft.h> 

using namespace std; 

const char fontNames[5][50] = { "helvetica", "arial", "courier", "times", "utopia" }; 
int sizes[5] = {10, 20, 30, 40, 50}; 
int numFonts = 5; 

void TestXft(Display* display, Window& win, GC& gc, const char *fontName, int size); 

Window create_simple_window(Display* display, int width, int height, int x, int y) 
{ 
    int screen_num = DefaultScreen(display); 
    int win_border_width = 2; 
    Window win; 
    win = XCreateSimpleWindow(display, RootWindow(display, screen_num), x, y, 
      width, height, win_border_width, 
      BlackPixel(display, screen_num), 
      WhitePixel(display, screen_num)); 

    XMapWindow(display, win); 

    XFlush(display); 

    return win; 
} 

GC create_gc(Display* display, Window win) 
{ 
    GC gc; 
    unsigned long valuemask = 0; 
    XGCValues values; 

    gc = XCreateGC(display, win, valuemask, &values); 

    if (gc < 0) 
    { 
     fprintf(stderr, "XCreateGC: \n"); 
    } 
    return gc; 
} 

int main(int argc, char* argv[]) 
{ 
    int screen_num; 
    Window win; 
    unsigned int display_width, display_height; 
    GC gc; 
    unsigned long count = 0; 

    while(true) 
    {  
     cout << "\nIteration: " << ++count << endl; 

     Display* display = XOpenDisplay(NULL); 
     if (display == NULL) 
     { 
      printf("Cannot connect to X server\n"); 
      exit(1); 
     } 

     screen_num = DefaultScreen(display); 
     display_width = 500; 
     display_height = 500; 

     win = create_simple_window(display, display_width, display_height, 0, 0); 
     XMapWindow(display, win); 

     XMoveWindow(display, win, 1000, 600); 

     gc = create_gc(display, win); 

     for(int i = 0; i < numFonts; i++) 
     { 
      TestXft(display, win, gc, fontNames[i], sizes[i]); 
     } 

     XUnmapWindow(display, win); 
     XFreeGC(display, gc); 
     XSync(display, false); 
     XCloseDisplay(display); 
    } 
    return 0; 
} 

void TestXft(Display* display, Window& win, GC& gc, const char *fontName, int size) 
{ 
    XftFont  *font = NULL; 
    XftDraw  *xftdraw = NULL; 
    XRenderColor xrcolor; 
    XftColor  xftcolor; 
    font = NULL; 

    Colormap colormap = XCreateColormap(display, win, DefaultVisual(display, DefaultScreen(display)), AllocNone); 

    font = XftFontOpen(display, DefaultScreen(display), XFT_FAMILY, XftTypeString, fontName, 
           XFT_SIZE, XftTypeDouble, (double) size, 
           XFT_SCALE, XftTypeDouble, 2.0, 
           NULL); 
    if (!font) 
    { 
     printf("Font not Found.\n"); 
     return; 
    } 

    xftdraw = XftDrawCreate(display, win, DefaultVisual(display,0), colormap); 

    xrcolor.red = 65535; 
    xrcolor.green= 0; 
    xrcolor.blue = 0; 
    xrcolor.alpha= 65535; 
    XftColorAllocValue(display, DefaultVisual(display,0), colormap, &xrcolor, &xftcolor); 

    const char *text = "RCB...RCB...RCB"; 
    XftDrawString8(xftdraw, &xftcolor, font, 200, 300 , (XftChar8 *) text, strlen(text)); 

    XftColorFree(display, DefaultVisual(display,0), colormap, &xftcolor); 
    XftDrawDestroy(xftdraw); 
    XftFontClose(display, font); 
    XFreeColormap(display, colormap); 
} 

回答

0

這是Xft庫中的一個錯誤,它會在多次打開和關閉顯示器時阻止它的使用。

XOpenDisplayXCloseDisplay移出該循環,將一個調用添加到XDestroyWindow,它將工作。

相關問題