diff --git a/include/winX.h b/include/winX.h index 76b4a58f4..dc34bd572 100644 --- a/include/winX.h +++ b/include/winX.h @@ -84,7 +84,7 @@ struct text_map_info_t { square_ascent, /* placement of changes. */ square_lbearing; -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFontStruct *font; #endif }; @@ -131,7 +131,12 @@ struct line_element { }; struct mesg_info_t { +#ifdef USE_XFT + Pixel fgpixel; /* Color for text drawing */ +#else + GC gc; /* GC for text drawing */ XFontStruct *fs; /* Font for the window. */ +#endif int num_lines; /* line count */ struct line_element *head; /* head of circular line queue */ struct line_element *line_here; /* current drawn line position */ @@ -139,11 +144,6 @@ struct mesg_info_t { /* bottom of screen */ struct line_element *last_pause_head; /* pointer to head of previous */ /* turn */ -#ifdef USE_XFT - Pixel fgpixel; /* Color for text drawing */ -#else - GC gc; /* GC for text drawing */ -#endif int char_width, /* Saved font information so we can */ char_height, /* calculate the correct placement */ char_ascent, /* of changes. */ @@ -161,7 +161,9 @@ struct mesg_info_t { struct status_info_t { struct text_buffer text; /* Just a text buffer. */ Pixel fg, bg; /* foreground and background */ +#ifndef USE_XFT XFontStruct *fs; /* Status window font structure. */ +#endif Dimension spacew; /* width of one space */ Position x, y[3]; /* x coord (not used), y for up to three lines */ Dimension wd, ht; /* width (not used), height (same for all lines) */ @@ -202,7 +204,9 @@ struct menu_info_t { struct menu curr_menu; /* Menu being displayed. */ struct menu new_menu; /* New menu being built. */ +#ifndef USE_XFT XFontStruct *fs; /* Font for the window. */ +#endif long menu_count; /* number entered by user */ Dimension line_height; /* Total height of a line of text. */ Dimension internal_height; /* Internal height between widget & border */ @@ -225,10 +229,6 @@ struct menu_info_t { */ struct text_info_t { struct text_buffer text; - XFontStruct *fs; /* Font for the text window. */ - int max_width; /* Width of widest line so far. */ - int extra_width, /* Sum of left and right border widths. */ - extra_height; /* Sum of top and bottom border widths. */ boolean blocked; /* */ boolean destroy_on_ack; /* Destroy this window when acknowledged. */ #ifdef GRAPHIC_TOMBSTONE @@ -250,8 +250,10 @@ struct xwindow { boolean nh_colors_inited; XColor nh_colors[CLR_MAX]; +#ifndef USE_XFT XFontStruct *boldfs; /* Bold font */ Display *boldfs_dpy; /* Bold font display */ +#endif char *title; union { @@ -361,8 +363,10 @@ extern boolean X11_blink; } while (0) /* ### Window.c ### */ +#ifndef USE_XFT extern Font WindowFont(Widget); extern XFontStruct *WindowFontStruct(Widget); +#endif /* ### dialogs.c ### */ extern Widget CreateDialog(Widget, String, XtCallbackProc, XtCallbackProc); diff --git a/win/X11/Window.c b/win/X11/Window.c index d9b4f3edb..401caaa2d 100644 --- a/win/X11/Window.c +++ b/win/X11/Window.c @@ -168,6 +168,7 @@ WindowClassRec windowClassRec = { WidgetClass windowWidgetClass = (WidgetClass) &windowClassRec; +#ifndef USE_XFT Font WindowFont(Widget w) { @@ -179,3 +180,4 @@ WindowFontStruct(Widget w) { return ((WindowWidget) w)->window.font; } +#endif diff --git a/win/X11/winX.c b/win/X11/winX.c index 79adc1d6b..c59ab5fab 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1161,8 +1161,10 @@ X11_create_nhwindow(int type) wp->pixel_height = 0; wp->keep_window = FALSE; wp->nh_colors_inited = FALSE; +#ifndef USE_XFT wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; +#endif wp->title = (char *) 0; switch (type) { @@ -1304,11 +1306,13 @@ X11_destroy_nhwindow(winid window) WIN_INVEN = WIN_ERR; } +#ifndef USE_XFT if (wp->boldfs) { XFreeFont(wp->boldfs_dpy, wp->boldfs); wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; } +#endif if (wp->title) { free(wp->title); @@ -3158,7 +3162,6 @@ X11_italic_font(Display *display, XFontStruct *font) return font2; } -#endif /* !USE_XFT */ #ifdef ENHANCED_SYMBOLS /* Given an XFontStruct, return a corresponding font that supports Unicode */ @@ -3202,6 +3205,7 @@ X11_unicode_font(Display *display, XFontStruct *font) return unifont; } #endif /* ENHANCED_SYMBOLS */ +#endif /* !USE_XFT */ #ifdef USE_XFT diff --git a/win/X11/winmap.c b/win/X11/winmap.c index c6733f76c..a09691957 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -72,12 +72,15 @@ static void X11_free_gc(struct xwindow *wp, GC gc, X11_color color); static void X11_draw_image_string(Display *display, Drawable d, GC ggc, int x, int y, const X11_map_symbol *string, int length); -#endif /* ?USE_XFT */ #ifdef ENHANCED_SYMBOLS static void X11_set_map_font(struct xwindow *wp); #endif +#endif /* ?USE_XFT */ static Font X11_get_map_font(struct xwindow *wp); +#ifndef USE_XFT static XFontStruct *X11_get_map_font_struct(struct xwindow *wp); +#endif +static void get_text_gc(struct xwindow *, Font); static boolean init_tiles(struct xwindow *); static void set_button_values(Widget, int, int, unsigned); static void map_check_size_change(struct xwindow *); @@ -85,7 +88,6 @@ static void map_update(struct xwindow *, int, int, int, int, boolean); static void init_text(struct xwindow *); static void map_exposed(Widget, XtPointer, XtPointer); static void set_gc(Widget, Font, const char *, Pixel, GC *, GC *); -static void get_text_gc(struct xwindow *, Font); static void map_all_unexplored(struct map_info_t *); static void get_char_info(struct xwindow *); static void display_cursor(struct xwindow *); @@ -844,7 +846,11 @@ set_gc( GC *regular, GC *inverse) { XGCValues values; +#ifdef USE_XFT + XtGCMask mask = GCFunction | GCForeground | GCBackground; +#else XtGCMask mask = GCFunction | GCForeground | GCBackground | GCFont; +#endif Pixel curpixel; Arg arg[1]; @@ -1587,10 +1593,16 @@ X11_make_gc( values.background = bgpixel; } values.function = GXcopy; +#ifdef USE_XFT + ggc = XtGetGC(wp->w, + GCFunction | GCForeground | GCBackground, + &values); +#else values.font = X11_get_map_font(wp); ggc = XtGetGC(wp->w, GCFunction | GCForeground | GCBackground | GCFont, &values); +#endif } else { ggc = (cur_inv ? text_map->inv_copy_gc : text_map->copy_gc); } @@ -1784,7 +1796,7 @@ create_map_window( map_info = wp->map_information = (struct map_info_t *) alloc(sizeof (struct map_info_t)); -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) X11_set_map_font(wp); #endif @@ -1835,7 +1847,7 @@ create_map_window( map_all_unexplored(map_info); } -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) static void X11_set_map_font(struct xwindow *wp) { @@ -1853,14 +1865,20 @@ X11_set_map_font(struct xwindow *wp) map_info->text_map.font = fs; } } -#endif +#endif /* ENHANCED_SYMBOLS && !USE_XFT */ static Font X11_get_map_font(struct xwindow *wp) { +#ifdef USE_XFT + nhUse(wp); + return 0; +#else /* !USE_XFT */ return X11_get_map_font_struct(wp)->fid; +#endif /* ?USE_XFT */ } +#ifndef USE_XFT static XFontStruct * X11_get_map_font_struct(struct xwindow *wp) { @@ -1876,6 +1894,7 @@ X11_get_map_font_struct(struct xwindow *wp) return WindowFontStruct(wp->w); #endif } +#endif /* USE_XFT */ /* * Destroy this map window. @@ -1900,7 +1919,7 @@ destroy_map_window(struct xwindow *wp) } /* Free the font structure if we allocated one */ -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFreeFont(XtDisplay(wp->w), text_map->font); #endif diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 69df458b0..aa707a186 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -37,7 +37,7 @@ static struct line_element *get_previous(struct line_element *); static void set_circle_buf(struct mesg_info_t *, int); -static char *split(char *, XFontStruct *, Dimension); +static char *split(char *, struct xwindow *, Dimension); static void add_line(struct mesg_info_t *, const char *); static void redraw_message_window(struct xwindow *); static void mesg_check_size_change(struct xwindow *); @@ -83,7 +83,9 @@ create_message_window(struct xwindow *wp, /* window pointer */ wp->mesg_information = mesg_info = (struct mesg_info_t *) alloc(sizeof (struct mesg_info_t)); +#ifndef USE_XFT mesg_info->fs = 0; +#endif mesg_info->num_lines = 0; mesg_info->head = mesg_info->line_here = mesg_info->last_pause = mesg_info->last_pause_head = (struct line_element *) 0; @@ -151,26 +153,37 @@ create_message_window(struct xwindow *wp, /* window pointer */ * is appResources.message_lines high and DEFAULT_MESSAGE_WIDTH wide. */ + /* Save character information for fast use later. */ +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); + XGlyphInfo extents; + mesg_info->char_width = font->max_advance_width; + mesg_info->char_height = font->height; + mesg_info->char_ascent = font->ascent; + mesg_info->char_lbearing = 0; + /* Xft seems to offer no direct way to distinguish proportional from + monospaced fonts. Assume that "!" will be narrower than maximum. */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "!", 1, &extents); + int min_width = extents.width - extents.x; + /* "Maximum" is likely to include things like Chinese characters that + * display at double width. Use the width of "M". */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "M", 1, &extents); + int max_width = extents.width - extents.x; + X11_release_font(wp->w, font); +#else /* Get the font information. */ num_args = 0; XtSetArg(args[num_args], XtNfont, &mesg_info->fs); num_args++; XtGetValues(wp->w, args, num_args); - /* Save character information for fast use later. */ -#ifdef USE_XFT - XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); - mesg_info->char_width = font->max_advance_width; - mesg_info->char_height = font->height; - mesg_info->char_ascent = font->ascent; - mesg_info->char_lbearing = 0; - X11_release_font(wp->w, font); -#else mesg_info->char_width = mesg_info->fs->max_bounds.width; mesg_info->char_height = mesg_info->fs->max_bounds.ascent + mesg_info->fs->max_bounds.descent; mesg_info->char_ascent = mesg_info->fs->max_bounds.ascent; mesg_info->char_lbearing = -mesg_info->fs->min_bounds.lbearing; + int min_width = mesg_info->fs->min_bounds.width; + int max_width = mesg_info->fs->max_bounds.width; #endif get_gc(wp->w, mesg_info); @@ -178,12 +191,11 @@ create_message_window(struct xwindow *wp, /* window pointer */ wp->pixel_height = ((int) iflags.msg_history) * mesg_info->char_height; /* If a variable spaced font, only use 2/3 of the default size */ - if (mesg_info->fs->min_bounds.width != mesg_info->fs->max_bounds.width) { + if (min_width != max_width) { wp->pixel_width = ((2 * DEFAULT_MESSAGE_WIDTH) / 3) - * mesg_info->fs->max_bounds.width; + * max_width; } else - wp->pixel_width = - (DEFAULT_MESSAGE_WIDTH * mesg_info->fs->max_bounds.width); + wp->pixel_width = (DEFAULT_MESSAGE_WIDTH * max_width); /* Set the new width and height. */ num_args = 0; @@ -259,7 +271,7 @@ append_message(struct xwindow *wp, const char *str) remainder = buf; do { mark = remainder; - remainder = split(mark, wp->mesg_information->fs, wp->pixel_width); + remainder = split(mark, wp, wp->pixel_width); add_line(wp->mesg_information, mark); } while (remainder); } @@ -366,10 +378,16 @@ set_circle_buf(struct mesg_info_t *mesg_info, int count) * not, back up from the end by words until we find a place to split. */ static char * -split(char *s, - XFontStruct *fs, /* Font for the window. */ +split( + char *s, + struct xwindow *wp, Dimension pixel_width) { +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); +#else + XFontStruct *fs = wp->mesg_information->fs; /* Font for the window. */ +#endif char save, *end, *remainder; save = '\0'; @@ -377,7 +395,18 @@ split(char *s, end = eos(s); /* point to null at end of string */ /* assume that if end == s, XXXXXX returns 0) */ - while ((Dimension) XTextWidth(fs, s, (int) strlen(s)) > pixel_width) { + while (TRUE) { +#ifdef USE_XFT + XGlyphInfo extents; + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) s, strlen(s), &extents); + if (extents.width - extents.x < pixel_width) { + break; + } +#else + if ((Dimension) XTextWidth(fs, s, (int) strlen(s)) < pixel_width) { + break; + } +#endif *end-- = save; while (*end != ' ') { if (end == s) @@ -388,6 +417,9 @@ split(char *s, *end = '\0'; remainder = end + 1; } +#ifdef USE_XFT + X11_release_font(wp->w, font); +#endif return remainder; } diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 8a5e61cd7..ee6247029 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -136,16 +136,10 @@ add_to_text_window(struct xwindow *wp, int attr, /* currently unused */ const char *str) { struct text_info_t *text_info = wp->text_information; - int width; nhUse(attr); append_text_buffer(&text_info->text, str, FALSE); - - /* Calculate text width and save longest line */ - width = XTextWidth(text_info->fs, str, (int) strlen(str)); - if (width > text_info->max_width) - text_info->max_width = width; } void @@ -208,9 +202,6 @@ create_text_window(struct xwindow *wp) (struct text_info_t *) alloc(sizeof(struct text_info_t)); init_text_buffer(&text_info->text); - text_info->max_width = 0; - text_info->extra_width = 0; - text_info->extra_height = 0; text_info->blocked = FALSE; text_info->destroy_on_ack = TRUE; /* Ok to destroy before display */ #ifdef GRAPHIC_TOMBSTONE @@ -269,15 +260,6 @@ create_text_window(struct xwindow *wp) args, /* set some values */ num_args); /* number of values to set */ X11_wrap_widget_if_Xft(wp->w, NHW_TEXT); - - /* Get the font and margin information. */ - num_args = 0; - XtSetArg(args[num_args], XtNfont, &text_info->fs); - num_args++; - XtGetValues(wp->w, args, num_args); - - text_info->extra_width = 0; - text_info->extra_height = 0; } void @@ -495,12 +477,16 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, XDestroyImage(rip_image); /* data bytes free'd also */ } - mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.graphics_exposures = False; XtSetArg(args[0], XtNforeground, &values.foreground); XtGetValues(w, args, 1); values.function = GXcopy; +#ifdef USE_XFT + mask = GCFunction | GCForeground | GCGraphicsExposures; +#else + mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.font = WindowFont(w); +#endif ggc = XtGetGC(w, mask, &values); if (rip_pixmap != None) {