Changeset 4141 for libcaca


Ignore:
Timestamp:
Dec 17, 2009, 2:46:30 AM (10 years ago)
Author:
Sam Hocevar
Message:

Use XwcDrawString? in the X11 driver if font sets are available.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcaca/trunk/caca/driver/x11.c

    r4140 r4141  
    2525#include <X11/Xutil.h>
    2626#include <X11/keysym.h>
    27 #if defined(HAVE_X11_XKBLIB_H)
     27#if defined HAVE_X11_XKBLIB_H
    2828#   include <X11/XKBlib.h>
    2929#endif
     
    5353    int font_width, font_height;
    5454    int colors[4096];
     55#if defined X_HAVE_UTF8_STRING
     56    XFontSet font_set;
     57#endif
    5558    Font font;
    5659    XFontStruct *font_struct;
     
    5962    Atom wm_protocols;
    6063    Atom wm_delete_window;
    61 #if defined(HAVE_X11_XKBLIB_H)
     64#if defined HAVE_X11_XKBLIB_H
    6265    Bool autorepeat;
    6366#endif
     
    7881    Colormap colormap;
    7982    XSetWindowAttributes x11_winattr;
     83#if defined X_HAVE_UTF8_STRING
     84    XVaNestedList list;
     85#endif
    8086    int (*old_error_handler)(Display *, XErrorEvent *);
    8187    char const *fonts[] = { NULL, "8x13bold", "fixed", NULL }, **parser;
     
    8793    dp->drv.p = malloc(sizeof(struct driver_private));
    8894
    89 #if defined(HAVE_GETENV)
     95#if defined HAVE_GETENV
    9096    geometry = getenv("CACA_GEOMETRY");
    9197    if(geometry && *geometry)
     
    104110        return -1;
    105111
    106 #if defined(HAVE_GETENV)
     112#if defined HAVE_GETENV
    107113    fonts[0] = getenv("CACA_FONT");
    108114    if(fonts[0] && *fonts[0])
     
    118124    for( ; ; parser++)
    119125    {
     126#if defined X_HAVE_UTF8_STRING
     127        char **missing_charset_list;
     128        char *def_string;
     129        int missing_charset_count;
     130#endif
    120131        uint32_t font_max_char;
    121132
     
    126137            return -1;
    127138        }
     139
     140#if defined X_HAVE_UTF8_STRING
     141        dp->drv.p->font_set = XCreateFontSet(dp->drv.p->dpy, *parser,
     142                                             &missing_charset_list,
     143                                             &missing_charset_count,
     144                                             &def_string);
     145        if (missing_charset_list)
     146            XFreeStringList(missing_charset_list);
     147
     148        if (!dp->drv.p->font_set || missing_charset_count)
     149        {
     150            char buf[BUFSIZ];
     151
     152            if (dp->drv.p->font_set)
     153                XFreeFontSet(dp->drv.p->dpy, dp->drv.p->font_set);
     154            snprintf(buf, BUFSIZ - 1, "%s,*", *parser);
     155            dp->drv.p->font_set = XCreateFontSet(dp->drv.p->dpy, buf,
     156                                                 &missing_charset_list,
     157                                                 &missing_charset_count,
     158                                                 &def_string);
     159            if (missing_charset_list)
     160                XFreeStringList(missing_charset_list);
     161        }
     162
     163        if (dp->drv.p->font_set)
     164            break;
     165#endif
    128166
    129167        dp->drv.p->font = XLoadFont(dp->drv.p->dpy, *parser);
     
    161199    XSetErrorHandler(old_error_handler);
    162200
    163     dp->drv.p->font_width = 0;
    164     if(dp->drv.p->font_struct->per_char
    165         && !dp->drv.p->font_struct->min_byte1
    166         && dp->drv.p->font_struct->min_char_or_byte2 <= 0x21
    167         && dp->drv.p->font_struct->max_char_or_byte2 >= 0x7e)
    168     {
    169         for(i = 0x21; i < 0x7f; i++)
    170         {
    171             int cw = dp->drv.p->font_struct->per_char[i
    172                            - dp->drv.p->font_struct->min_char_or_byte2].width;
    173             if(cw > dp->drv.p->font_width)
    174                 dp->drv.p->font_width = cw;
    175         }
    176     }
    177 
    178     if(!dp->drv.p->font_width)
    179         dp->drv.p->font_width = dp->drv.p->font_struct->max_bounds.width;
    180 
    181     dp->drv.p->font_height = dp->drv.p->font_struct->max_bounds.ascent
    182                          + dp->drv.p->font_struct->max_bounds.descent;
    183     dp->drv.p->font_offset = dp->drv.p->font_struct->max_bounds.descent;
     201    /* Set font width to the largest character in the set */
     202#if defined X_HAVE_UTF8_STRING
     203    if (dp->drv.p->font_set)
     204    {
     205        XFontSetExtents *ex = XExtentsOfFontSet(dp->drv.p->font_set);
     206        dp->drv.p->font_width =
     207             XmbTextEscapement(dp->drv.p->font_set, "CAca", 4) / 4;
     208        dp->drv.p->font_height = ex->max_logical_extent.height;
     209        dp->drv.p->font_offset = ex->max_logical_extent.height
     210                                  + ex->max_logical_extent.y;
     211    }
     212    else
     213#endif
     214    {
     215        dp->drv.p->font_width = 0;
     216        if(dp->drv.p->font_struct->per_char
     217            && !dp->drv.p->font_struct->min_byte1
     218            && dp->drv.p->font_struct->min_char_or_byte2 <= 0x21
     219            && dp->drv.p->font_struct->max_char_or_byte2 >= 0x7e)
     220        {
     221            for(i = 0x21; i < 0x7f; i++)
     222            {
     223                int cw = dp->drv.p->font_struct->per_char[i
     224                            - dp->drv.p->font_struct->min_char_or_byte2].width;
     225                if(cw > dp->drv.p->font_width)
     226                    dp->drv.p->font_width = cw;
     227            }
     228        }
     229
     230        if(!dp->drv.p->font_width)
     231            dp->drv.p->font_width = dp->drv.p->font_struct->max_bounds.width;
     232
     233        dp->drv.p->font_height = dp->drv.p->font_struct->max_bounds.ascent
     234                                  + dp->drv.p->font_struct->max_bounds.descent;
     235        dp->drv.p->font_offset = dp->drv.p->font_struct->max_bounds.descent;
     236    }
    184237
    185238    colormap = DefaultColormap(dp->drv.p->dpy, DefaultScreen(dp->drv.p->dpy));
     
    222275    dp->drv.p->gc = XCreateGC(dp->drv.p->dpy, dp->drv.p->window, 0, NULL);
    223276    XSetForeground(dp->drv.p->dpy, dp->drv.p->gc, dp->drv.p->colors[0x888]);
    224     XSetFont(dp->drv.p->dpy, dp->drv.p->gc, dp->drv.p->font);
     277#if defined X_HAVE_UTF8_STRING
     278    if (!dp->drv.p->font_set)
     279#endif
     280        XSetFont(dp->drv.p->dpy, dp->drv.p->gc, dp->drv.p->font);
    225281
    226282    for(;;)
     
    232288    }
    233289
    234 #if defined(HAVE_X11_XKBLIB_H)
     290#if defined HAVE_X11_XKBLIB_H
    235291    /* Disable autorepeat */
    236292    XkbSetDetectableAutoRepeat(dp->drv.p->dpy, True, &dp->drv.p->autorepeat);
     
    258314    dp->drv.p->dirty_cursor_y = -1;
    259315
     316#if defined X_HAVE_UTF8_STRING
     317    list = XVaCreateNestedList(0, XNFontSet, dp->drv.p->font_set, NULL);
    260318    dp->drv.p->im = XOpenIM(dp->drv.p->dpy, NULL, NULL, NULL);
    261     dp->drv.p->ic = XCreateIC(dp->drv.p->im, XNInputStyle,
    262                               XIMPreeditNothing | XIMStatusNothing, NULL);
     319    dp->drv.p->ic = XCreateIC(dp->drv.p->im,
     320                          XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
     321                          XNClientWindow, dp->drv.p->window,
     322                          XNPreeditAttributes, list,
     323                          XNStatusAttributes, list,
     324                          NULL);
     325#endif
    263326
    264327    return 0;
     
    268331{
    269332    XSync(dp->drv.p->dpy, False);
    270 #if defined(HAVE_X11_XKBLIB_H)
     333#if defined HAVE_X11_XKBLIB_H
    271334    if(!dp->drv.p->autorepeat)
    272335        XAutoRepeatOn(dp->drv.p->dpy);
    273336#endif
    274337    XFreePixmap(dp->drv.p->dpy, dp->drv.p->pixmap);
    275     XFreeFont(dp->drv.p->dpy, dp->drv.p->font_struct);
     338#if defined X_HAVE_UTF8_STRING
     339    if (dp->drv.p->font_set)
     340        XFreeFontSet(dp->drv.p->dpy, dp->drv.p->font_set);
     341    else
     342#endif
     343        XFreeFont(dp->drv.p->dpy, dp->drv.p->font_struct);
    276344    XFreeGC(dp->drv.p->dpy, dp->drv.p->gc);
    277345    XUnmapWindow(dp->drv.p->dpy, dp->drv.p->window);
    278346    XDestroyWindow(dp->drv.p->dpy, dp->drv.p->window);
     347#if defined X_HAVE_UTF8_STRING
    279348    XDestroyIC(dp->drv.p->ic);
    280349    XCloseIM(dp->drv.p->im);
     350#endif
    281351    XCloseDisplay(dp->drv.p->dpy);
    282352
     
    666736    Pixmap px = dp->drv.p->pixmap;
    667737    GC gc = dp->drv.p->gc;
    668     XChar2b ch16;
    669738    int fw;
    670739
     
    823892
    824893#if defined X_HAVE_UTF8_STRING
    825     if(ch >= 0x00000020)
    826 #else
    827     if(ch >= 0x00000020 && ch <= dp->drv.p->max_char)
    828 #endif
    829     {
    830         ch16.byte1 = (uint8_t)(ch >> 8);
    831         ch16.byte2 = (uint8_t)ch;
     894    if (dp->drv.p->font_set)
     895    {
     896        wchar_t wch = ch;
     897        XwcDrawString(dpy, px, dp->drv.p->font_set, gc,
     898                      x + (fw - w) / 2, yoff, &wch, 1);
    832899    }
    833900    else
    834     {
    835         ch16.byte1 = 0;
    836         ch16.byte2 = caca_utf32_to_ascii(ch);
    837     }
    838 
    839     XDrawString16(dpy, px, gc,
    840                   x + (ch16.byte1 ? 0 : (fw - w) / 2), yoff, &ch16, 1);
     901#endif
     902    {
     903        XChar2b ch16;
     904
     905#if !defined X_HAVE_UTF8_STRING
     906        if(ch > dp->drv.p->max_char)
     907        {
     908            ch16.byte1 = 0;
     909            ch16.byte2 = caca_utf32_to_ascii(ch);
     910        }
     911        else
     912#endif
     913        {
     914            ch16.byte1 = (uint8_t)(ch >> 8);
     915            ch16.byte2 = (uint8_t)ch;
     916        }
     917
     918        XDrawString16(dpy, px, gc,
     919                      x + (ch16.byte1 ? 0 : (fw - w) / 2), yoff, &ch16, 1);
     920    }
    841921}
    842922
     
    847927int x11_install(caca_display_t *dp)
    848928{
    849 #if defined(HAVE_GETENV)
     929#if defined HAVE_GETENV
    850930    if(!getenv("DISPLAY") || !*(getenv("DISPLAY")))
    851931        return -1;
Note: See TracChangeset for help on using the changeset viewer.