diff options
author | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-02 15:02:49 +0100 |
---|---|---|
committer | Mike Gabriel <mike.gabriel@das-netzwerkteam.de> | 2015-02-02 15:02:49 +0100 |
commit | b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 (patch) | |
tree | 4361edef0d42d5bf5ac984ef72b4fac35426eae7 /nx-X11/programs/xterm/fontutils.c | |
parent | 0d5a83e986f39982c0924652a3662e60b1f23162 (diff) | |
download | nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.gz nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.bz2 nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.zip |
massive reduction of unneeded files
Diffstat (limited to 'nx-X11/programs/xterm/fontutils.c')
-rw-r--r-- | nx-X11/programs/xterm/fontutils.c | 2371 |
1 files changed, 0 insertions, 2371 deletions
diff --git a/nx-X11/programs/xterm/fontutils.c b/nx-X11/programs/xterm/fontutils.c deleted file mode 100644 index fb4c6373c..000000000 --- a/nx-X11/programs/xterm/fontutils.c +++ /dev/null @@ -1,2371 +0,0 @@ -/* $XTermId: fontutils.c,v 1.184 2005/11/03 13:17:27 tom Exp $ */ - -/* - * $XFree86: xc/programs/xterm/fontutils.c,v 1.55 2005/11/03 13:17:27 dickey Exp $ - */ - -/************************************************************ - -Copyright 1998-2004,2005 by Thomas E. Dickey - - All Rights Reserved - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name(s) of the above copyright -holders shall not be used in advertising or otherwise to promote the -sale, use or other dealings in this Software without prior written -authorization. - -********************************************************/ - -/* - * A portion of this module (for FontNameProperties) was adapted from EMU 1.3; - * it constructs font names with specific properties changed, e.g., for bold - * and double-size characters. - */ - -#define RES_OFFSET(field) XtOffsetOf(SubResourceRec, field) - -#include <fontutils.h> -#include <X11/Xmu/Drawing.h> - -#include <main.h> -#include <data.h> -#include <menu.h> -#include <xstrings.h> -#include <xterm.h> - -#include <stdio.h> -#include <ctype.h> - -/* from X11/Xlibint.h - not all vendors install this file */ -#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ - (((cs)->rbearing|(cs)->lbearing| \ - (cs)->ascent|(cs)->descent) == 0)) - -#define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \ -{ \ - cs = def; \ - if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ -{ \ - cs = def; \ - if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ - col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[((row - fs->min_byte1) * \ - (fs->max_char_or_byte2 - \ - fs->min_char_or_byte2 + 1)) + \ - (col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define MAX_FONTNAME 200 - -/* - * A structure to hold the relevant properties from a font - * we need to make a well formed font name for it. - */ -typedef struct { - /* registry, foundry, family */ - char *beginning; - /* weight */ - char *weight; - /* slant */ - char *slant; - /* wideness */ - char *wideness; - /* add style */ - char *add_style; - int pixel_size; - char *point_size; - int res_x; - int res_y; - char *spacing; - int average_width; - /* charset registry, charset encoding */ - char *end; -} FontNameProperties; - -#if OPT_SHIFT_FONTS -static void lookupOneFontSize(TScreen *, int); -#endif - -/* - * Returns the fields from start to stop in a dash- separated string. This - * function will modify the source, putting '\0's in the appropiate place and - * moving the beginning forward to after the '\0' - * - * This will NOT work for the last field (but we won't need it). - */ -static char * -n_fields(char **source, int start, int stop) -{ - int i; - char *str, *str1; - - /* - * find the start-1th dash - */ - for (i = start - 1, str = *source; i; i--, str++) - if ((str = strchr(str, '-')) == 0) - return 0; - - /* - * find the stopth dash - */ - for (i = stop - start + 1, str1 = str; i; i--, str1++) - if ((str1 = strchr(str1, '-')) == 0) - return 0; - - /* - * put a \0 at the end of the fields - */ - *(str1 - 1) = '\0'; - - /* - * move source forward - */ - *source = str1; - - return str; -} - -/* - * Gets the font properties from a given font structure. We use the FONT name - * to find them out, since that seems easier. - * - * Returns a pointer to a static FontNameProperties structure - * or NULL on error. - */ -static FontNameProperties * -get_font_name_props(Display * dpy, XFontStruct * fs, char *result) -{ - static FontNameProperties props; - static char *last_name; - - XFontProp *fp; - int i; - Atom fontatom = XInternAtom(dpy, "FONT", False); - char *name; - char *str; - - /* - * first get the full font name - */ - for (name = 0, i = 0, fp = fs->properties; - i < fs->n_properties; - i++, fp++) - if (fp->name == fontatom) - name = XGetAtomName(dpy, fp->card32); - - if (name == 0) - return 0; - - /* - * XGetAtomName allocates memory - don't leak - */ - if (last_name != 0) - XFree(last_name); - last_name = name; - - if (result != 0) { - if (strlen(name) < MAX_FONTNAME - 1) { - strcpy(result, name); - } else { - TRACE(("fontname too large: %s\n", name)); - return 0; - } - } - - /* - * Now split it up into parts and put them in - * their places. Since we are using parts of - * the original string, we must not free the Atom Name - */ - - /* registry, foundry, family */ - if ((props.beginning = n_fields(&name, 1, 3)) == 0) - return 0; - - /* weight is the next */ - if ((props.weight = n_fields(&name, 1, 1)) == 0) - return 0; - - /* slant */ - if ((props.slant = n_fields(&name, 1, 1)) == 0) - return 0; - - /* width */ - if ((props.wideness = n_fields(&name, 1, 1)) == 0) - return 0; - - /* add style */ - if ((props.add_style = n_fields(&name, 1, 1)) == 0) - return 0; - - /* pixel size */ - if ((str = n_fields(&name, 1, 1)) == 0) - return 0; - if ((props.pixel_size = atoi(str)) == 0) - return 0; - - /* point size */ - if ((props.point_size = n_fields(&name, 1, 1)) == 0) - return 0; - - /* res_x */ - if ((str = n_fields(&name, 1, 1)) == 0) - return 0; - if ((props.res_x = atoi(str)) == 0) - return 0; - - /* res_y */ - if ((str = n_fields(&name, 1, 1)) == 0) - return 0; - if ((props.res_y = atoi(str)) == 0) - return 0; - - /* spacing */ - if ((props.spacing = n_fields(&name, 1, 1)) == 0) - return 0; - - /* average width */ - if ((str = n_fields(&name, 1, 1)) == 0) - return 0; - if ((props.average_width = atoi(str)) == 0) - return 0; - - /* the rest: charset registry and charset encoding */ - props.end = name; - - return &props; -} - -#define ALLOCHUNK(n) ((n | 127) + 1) - -static void -alloca_fontname(char **result, unsigned next) -{ - unsigned last = (*result != 0) ? strlen(*result) : 0; - unsigned have = (*result != 0) ? ALLOCHUNK(last) : 0; - unsigned want = last + next + 2; - - if (want >= have) { - want = ALLOCHUNK(want); - if (last != 0) { - *result = TypeRealloc(char, want, *result); - } else { - if ((*result = TypeMallocN(char, want)) != 0) - **result = '\0'; - } - } -} - -static void -append_fontname_str(char **result, char *value) -{ - if (value == 0) - value = "*"; - alloca_fontname(result, strlen(value)); - if (*result != 0) { - if (**result != '\0') - strcat(*result, "-"); - strcat(*result, value); - } -} - -static void -append_fontname_num(char **result, int value) -{ - if (value < 0) { - append_fontname_str(result, "*"); - } else { - char temp[100]; - sprintf(temp, "%d", value); - append_fontname_str(result, temp); - } -} - -/* - * Take the given font props and try to make a well formed font name specifying - * the same base font and size and everything, but with different weight/width - * according to the parameters. The return value is allocated, should be freed - * by the caller. - */ -static char * -derive_font_name(FontNameProperties * props, - char *use_weight, - int use_average_width, - char *use_encoding) -{ - char *result = 0; - - append_fontname_str(&result, props->beginning); - append_fontname_str(&result, use_weight); - append_fontname_str(&result, props->slant); - append_fontname_str(&result, 0); - append_fontname_str(&result, 0); - append_fontname_num(&result, props->pixel_size); - append_fontname_str(&result, props->point_size); - append_fontname_num(&result, props->res_x); - append_fontname_num(&result, props->res_y); - append_fontname_str(&result, props->spacing); - append_fontname_num(&result, use_average_width); - append_fontname_str(&result, use_encoding); - - return result; -} - -static char * -bold_font_name(FontNameProperties * props, int use_average_width) -{ - return derive_font_name(props, "bold", use_average_width, props->end); -} - -#if OPT_WIDE_CHARS -#define derive_wide_font(props, weight) \ - derive_font_name(props, weight, props->average_width * 2, "ISO10646-1") - -static char * -wide_font_name(FontNameProperties * props) -{ - return derive_wide_font(props, "medium"); -} - -static char * -widebold_font_name(FontNameProperties * props) -{ - return derive_wide_font(props, "bold"); -} -#endif /* OPT_WIDE_CHARS */ - -#if OPT_DEC_CHRSET -/* - * Take the given font props and try to make a well formed font name specifying - * the same base font but changed depending on the given attributes and chrset. - * - * For double width fonts, we just double the X-resolution, for double height - * fonts we double the pixel-size and Y-resolution - */ -char * -xtermSpecialFont(TScreen * screen, unsigned atts, unsigned chrset) -{ -#if OPT_TRACE - static char old_spacing[80]; - static FontNameProperties old_props; -#endif - FontNameProperties *props; - char *result = 0; - char *weight; - int pixel_size; - int res_x; - int res_y; - - props = get_font_name_props(screen->display, screen->fnt_norm, (char *) 0); - if (props == 0) - return result; - - pixel_size = props->pixel_size; - res_x = props->res_x; - res_y = props->res_y; - if (atts & BOLD) - weight = "bold"; - else - weight = props->weight; - - if (CSET_DOUBLE(chrset)) - res_x *= 2; - - if (chrset == CSET_DHL_TOP - || chrset == CSET_DHL_BOT) { - res_y *= 2; - pixel_size *= 2; - } -#if OPT_TRACE - if (old_props.res_x != res_x - || old_props.res_x != res_y - || old_props.pixel_size != pixel_size - || strcmp(old_props.spacing, props->spacing)) { - TRACE(("xtermSpecialFont(atts = %#x, chrset = %#x)\n", atts, chrset)); - TRACE(("res_x = %d\n", res_x)); - TRACE(("res_y = %d\n", res_y)); - TRACE(("point_size = %s\n", props->point_size)); - TRACE(("pixel_size = %d\n", pixel_size)); - TRACE(("spacing = %s\n", props->spacing)); - old_props.res_x = res_x; - old_props.res_x = res_y; - old_props.pixel_size = pixel_size; - old_props.spacing = strcpy(old_spacing, props->spacing); - } -#endif - - append_fontname_str(&result, props->beginning); - append_fontname_str(&result, weight); - append_fontname_str(&result, props->slant); - append_fontname_str(&result, props->wideness); - append_fontname_str(&result, props->add_style); - append_fontname_num(&result, pixel_size); - append_fontname_str(&result, props->point_size); - append_fontname_num(&result, (atts & NORESOLUTION) ? -1 : res_x); - append_fontname_num(&result, (atts & NORESOLUTION) ? -1 : res_y); - append_fontname_str(&result, props->spacing); - append_fontname_str(&result, 0); - append_fontname_str(&result, props->end); - - return result; -} -#endif /* OPT_DEC_CHRSET */ - -/* - * Case-independent comparison for font-names, including wildcards. - * XLFD allows '?' as a wildcard, but we do not handle that (no one seems - * to use it). - */ -static Bool -same_font_name(char *pattern, char *match) -{ - while (*pattern && *match) { - if (*pattern == *match) { - pattern++; - match++; - } else if (*pattern == '*' || *match == '*') { - if (same_font_name(pattern + 1, match)) { - return True; - } else if (same_font_name(pattern, match + 1)) { - return True; - } else { - return False; - } - } else { - int p = char2lower(*pattern++); - int m = char2lower(*match++); - if (p != m) - return False; - } - } - return (*pattern == *match); /* both should be NUL */ -} - -/* - * Double-check the fontname that we asked for versus what the font server - * actually gave us. The larger fixed fonts do not always have a matching bold - * font, and the font server may try to scale another font or otherwise - * substitute a mismatched font. - * - * If we cannot get what we requested, we will fallback to the original - * behavior, which simulates bold by overstriking each character at one pixel - * offset. - */ -static int -got_bold_font(Display * dpy, XFontStruct * fs, char *requested) -{ - char actual[MAX_FONTNAME]; - int got; - - if (get_font_name_props(dpy, fs, actual) == 0) - got = 0; - else - got = same_font_name(requested, actual); - return got; -} - -/* - * If the font server tries to adjust another font, it may not adjust it - * properly. Check that the bounding boxes are compatible. Otherwise we'll - * leave trash on the display when we mix normal and bold fonts. - */ -static int -same_font_size(XtermWidget xw, XFontStruct * nfs, XFontStruct * bfs) -{ - TRACE(("same_font_size height %d/%d, min %d/%d max %d/%d\n", - nfs->ascent + nfs->descent, - bfs->ascent + bfs->descent, - nfs->min_bounds.width, bfs->min_bounds.width, - nfs->max_bounds.width, bfs->max_bounds.width)); - return xw->screen.free_bold_box - || ((nfs->ascent + nfs->descent) == (bfs->ascent + bfs->descent) - && (nfs->min_bounds.width == bfs->min_bounds.width - || nfs->min_bounds.width == bfs->min_bounds.width + 1) - && (nfs->max_bounds.width == bfs->max_bounds.width - || nfs->max_bounds.width == bfs->max_bounds.width + 1)); -} - -/* - * Check if the font looks like it has fixed width - */ -static int -is_fixed_font(XFontStruct * fs) -{ - if (fs) - return (fs->min_bounds.width == fs->max_bounds.width); - return 1; -} - -/* - * Check if the font looks like a double width font (i.e. contains - * characters of width X and 2X - */ -#if OPT_WIDE_CHARS -static int -is_double_width_font(XFontStruct * fs) -{ - return ((2 * fs->min_bounds.width) == fs->max_bounds.width); -} -#else -#define is_double_width_font(fs) 0 -#endif - -#if OPT_WIDE_CHARS && OPT_RENDERFONT && defined(HAVE_TYPE_FCCHAR32) -#define HALF_WIDTH_TEST_STRING "1234567890" - -/* '1234567890' in Chinese characters in UTF-8 */ -#define FULL_WIDTH_TEST_STRING "\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89" \ - "\xe5\x9b\x9b\xe4\xba\x94" \ - "\xef\xa7\x91\xe4\xb8\x83\xe5\x85\xab" \ - "\xe4\xb9\x9d\xef\xa6\xb2" - -/* '1234567890' in Korean script in UTF-8 */ -#define FULL_WIDTH_TEST_STRING2 "\xec\x9d\xbc\xec\x9d\xb4\xec\x82\xbc" \ - "\xec\x82\xac\xec\x98\xa4" \ - "\xec\x9c\xa1\xec\xb9\xa0\xed\x8c\x94" \ - "\xea\xb5\xac\xec\x98\x81" - -#define HALF_WIDTH_CHAR1 0x0031 /* 'l' */ -#define HALF_WIDTH_CHAR2 0x0057 /* 'W' */ -#define FULL_WIDTH_CHAR1 0x4E00 /* CJK Ideograph 'number one' */ -#define FULL_WIDTH_CHAR2 0xAC00 /* Korean script syllable 'Ka' */ - -static int -is_double_width_font_xft(Display * dpy, XftFont * font) -{ - XGlyphInfo gi1, gi2; - FcChar32 c1 = HALF_WIDTH_CHAR1, c2 = HALF_WIDTH_CHAR2; - char *fwstr = FULL_WIDTH_TEST_STRING; - char *hwstr = HALF_WIDTH_TEST_STRING; - - /* Some Korean fonts don't have Chinese characters at all. */ - if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR1)) { - if (!XftCharExists(dpy, font, FULL_WIDTH_CHAR2)) - return 0; /* Not a CJK font */ - else /* a Korean font without CJK Ideographs */ - fwstr = FULL_WIDTH_TEST_STRING2; - } - - XftTextExtents32(dpy, font, &c1, 1, &gi1); - XftTextExtents32(dpy, font, &c2, 1, &gi2); - if (gi1.xOff != gi2.xOff) /* Not a fixed-width font */ - return 0; - - XftTextExtentsUtf8(dpy, font, (FcChar8 *) hwstr, (int) strlen(hwstr), &gi1); - XftTextExtentsUtf8(dpy, font, (FcChar8 *) fwstr, (int) strlen(fwstr), &gi2); - - /* - * fontconfig and Xft prior to 2.2(?) set the width of half-width - * characters identical to that of full-width character in CJK double-width - * (bi-width / monospace) font even though the former is half as wide as - * the latter. This was fixed sometime before the release of fontconfig - * 2.2 in early 2003. See - * http://bugzilla.mozilla.org/show_bug.cgi?id=196312 - * In the meantime, we have to check both possibilities. - */ - return ((2 * gi1.xOff == gi2.xOff) || (gi1.xOff == gi2.xOff)); -} -#else -#define is_double_width_font_xft(dpy, xftfont) 0 -#endif - -#define EmptyFont(fs) (fs != 0 \ - && ((fs)->ascent + (fs)->descent == 0 \ - || (fs)->max_bounds.width == 0)) - -#define FontSize(fs) (((fs)->ascent + (fs)->descent) \ - * (fs)->max_bounds.width) - -const VTFontNames * -xtermFontName(char *normal) -{ - static VTFontNames data; - memset(&data, 0, sizeof(data)); - data.f_n = normal; - return &data; -} - -static void -cache_menu_font_name(TScreen * screen, int fontnum, int which, const char *name) -{ - if (name != 0) { - char *last = screen->menu_font_names[fontnum][which]; - if (last != 0) { - if (strcmp(last, name)) { - free(last); - TRACE(("caching menu fontname %d.%d %s\n", fontnum, which, name)); - screen->menu_font_names[fontnum][which] = x_strdup(name); - } - } else { - TRACE(("caching menu fontname %d.%d %s\n", fontnum, which, name)); - screen->menu_font_names[fontnum][which] = x_strdup(name); - } - } -} - -int -xtermLoadFont(XtermWidget xw, - const VTFontNames * fonts, - Bool doresize, - int fontnum) -{ - TScreen *screen = &(xw->screen); - - VTFontNames myfonts; - /* FIXME: use XFreeFontInfo */ - FontNameProperties *fp; - XFontStruct *nfs = NULL; - XFontStruct *bfs = NULL; -#if OPT_WIDE_CHARS - XFontStruct *wfs = NULL; - XFontStruct *wbfs = NULL; -#endif - XGCValues xgcv; - unsigned long mask; - GC new_normalGC = NULL; - GC new_normalboldGC = NULL; - GC new_reverseGC = NULL; - GC new_reverseboldGC = NULL; - Pixel new_normal; - Pixel new_revers; - char *tmpname = NULL; - char normal[MAX_FONTNAME]; - Bool proportional = False; - - memset(&myfonts, 0, sizeof(myfonts)); - if (fonts != 0) - myfonts = *fonts; - if (myfonts.f_n == 0) - return 0; - - if (fontnum == fontMenu_fontescape - && myfonts.f_n != screen->MenuFontName(fontnum)) { - if ((tmpname = x_strdup(myfonts.f_n)) == 0) - return 0; - } - - TRACE(("xtermLoadFont #%d normal %s\n", fontnum, NonNull(myfonts.f_n))); - TRACE(("xtermLoadFont #%d bold %s\n", fontnum, NonNull(myfonts.f_b))); -#if OPT_WIDE_CHARS - TRACE(("xtermLoadFont #%d wide %s\n", fontnum, NonNull(myfonts.f_w))); - TRACE(("xtermLoadFont #%d w/bold %s\n", fontnum, NonNull(myfonts.f_wb))); -#endif - - if (!(nfs = XLoadQueryFont(screen->display, myfonts.f_n))) - goto bad; - if (EmptyFont(nfs)) - goto bad; /* can't use a 0-sized font */ - - strcpy(normal, myfonts.f_n); - if (myfonts.f_b == 0) { - fp = get_font_name_props(screen->display, nfs, normal); - if (fp != 0) { - myfonts.f_b = bold_font_name(fp, fp->average_width); - if ((bfs = XLoadQueryFont(screen->display, myfonts.f_b)) == 0) { - myfonts.f_b = bold_font_name(fp, -1); - bfs = XLoadQueryFont(screen->display, myfonts.f_b); - } - TRACE(("...derived bold %s\n", myfonts.f_b)); - } - if (fp == 0 || bfs == 0) { - bfs = nfs; - TRACE(("...cannot load a matching bold font\n")); - } else if (same_font_size(xw, nfs, bfs) - && got_bold_font(screen->display, bfs, myfonts.f_b)) { - TRACE(("...got a matching bold font\n")); - cache_menu_font_name(screen, fontnum, fBold, myfonts.f_b); - } else { - XFreeFont(screen->display, bfs); - bfs = nfs; - TRACE(("...did not get a matching bold font\n")); - } - } else if ((bfs = XLoadQueryFont(screen->display, myfonts.f_b)) == 0) { - bfs = nfs; - TRACE(("...cannot load bold font %s\n", myfonts.f_b)); - } else { - cache_menu_font_name(screen, fontnum, fBold, myfonts.f_b); - } - - /* - * If there is no widefont specified, fake it by doubling AVERAGE_WIDTH - * of normal fonts XLFD, and asking for it. This plucks out 18x18ja - * and 12x13ja as the corresponding fonts for 9x18 and 6x13. - */ - if_OPT_WIDE_CHARS(screen, { - char bold[MAX_FONTNAME]; - - if (myfonts.f_w != 0) { - cache_menu_font_name(screen, fontnum, fWide, myfonts.f_w); - } else if (!is_double_width_font(nfs)) { - fp = get_font_name_props(screen->display, nfs, normal); - if (fp != 0) { - myfonts.f_w = wide_font_name(fp); - TRACE(("...derived wide %s\n", myfonts.f_w)); - cache_menu_font_name(screen, fontnum, fWide, myfonts.f_w); - } - } - - if (myfonts.f_w) { - wfs = XLoadQueryFont(screen->display, myfonts.f_w); - } else { - wfs = nfs; - } - - if (myfonts.f_wb != 0) { - cache_menu_font_name(screen, fontnum, fWBold, myfonts.f_wb); - } else if (!is_double_width_font(bfs)) { - fp = get_font_name_props(screen->display, bfs, bold); - if (fp != 0) { - myfonts.f_wb = widebold_font_name(fp); - TRACE(("...derived wide/bold %s\n", myfonts.f_wb)); - cache_menu_font_name(screen, fontnum, fWBold, myfonts.f_wb); - } - } - - if (myfonts.f_wb) { - wbfs = XLoadQueryFont(screen->display, myfonts.f_wb); - } else if (is_double_width_font(bfs)) { - wbfs = bfs; - } else { - wbfs = wfs; - TRACE(("...cannot load wide bold font %s\n", myfonts.f_wb)); - } - - if (EmptyFont(wbfs)) - goto bad; /* can't use a 0-sized font */ - }); - - /* - * Most of the time this call to load the font will succeed, even if - * there is no wide font : the X server doubles the width of the - * normal font, or similar. - * - * But if it did fail for some reason, then nevermind. - */ - if (EmptyFont(bfs)) - goto bad; /* can't use a 0-sized font */ - - if (!same_font_size(xw, nfs, bfs) - && (is_fixed_font(nfs) && is_fixed_font(bfs))) { - TRACE(("...ignoring mismatched normal/bold fonts\n")); - XFreeFont(screen->display, bfs); - bfs = nfs; - } - - if_OPT_WIDE_CHARS(screen, { - if (wfs != 0 - && wbfs != 0 - && !same_font_size(xw, wfs, wbfs) - && (is_fixed_font(wfs) && is_fixed_font(wbfs))) { - TRACE(("...ignoring mismatched normal/bold wide fonts\n")); - XFreeFont(screen->display, wbfs); - wbfs = wfs; - } - }); - - /* - * Normal/bold fonts should be the same width. Also, the min/max - * values should be the same. - */ - if (!is_fixed_font(nfs) - || !is_fixed_font(bfs) - || nfs->max_bounds.width != bfs->max_bounds.width) { - TRACE(("Proportional font! normal %d/%d, bold %d/%d\n", - nfs->min_bounds.width, - nfs->max_bounds.width, - bfs->min_bounds.width, - bfs->max_bounds.width)); - proportional = True; - } - - if_OPT_WIDE_CHARS(screen, { - if (wfs != 0 - && wbfs != 0 - && (!is_fixed_font(wfs) - || !is_fixed_font(wbfs) - || wfs->max_bounds.width != wbfs->max_bounds.width)) { - TRACE(("Proportional font! wide %d/%d, wide bold %d/%d\n", - wfs->min_bounds.width, - wfs->max_bounds.width, - wbfs->min_bounds.width, - wbfs->max_bounds.width)); - proportional = True; - } - }); - - /* TODO : enforce that the width of the wide font is 2* the width - of the narrow font */ - - mask = (GCFont | GCForeground | GCBackground | GCGraphicsExposures | - GCFunction); - - new_normal = getXtermForeground(xw->flags, xw->cur_foreground); - new_revers = getXtermBackground(xw->flags, xw->cur_background); - - xgcv.font = nfs->fid; - xgcv.foreground = new_normal; - xgcv.background = new_revers; - xgcv.graphics_exposures = True; /* default */ - xgcv.function = GXcopy; - - new_normalGC = XtGetGC((Widget) xw, mask, &xgcv); - if (!new_normalGC) - goto bad; - - if (nfs == bfs) { /* there is no bold font */ - new_normalboldGC = new_normalGC; - } else { - xgcv.font = bfs->fid; - new_normalboldGC = XtGetGC((Widget) xw, mask, &xgcv); - if (!new_normalboldGC) - goto bad; - } - - xgcv.font = nfs->fid; - xgcv.foreground = new_revers; - xgcv.background = new_normal; - new_reverseGC = XtGetGC((Widget) xw, mask, &xgcv); - if (!new_reverseGC) - goto bad; - - if (nfs == bfs) { /* there is no bold font */ - new_reverseboldGC = new_reverseGC; - } else { - xgcv.font = bfs->fid; - new_reverseboldGC = XtGetGC((Widget) xw, mask, &xgcv); - if (!new_reverseboldGC) - goto bad; - } - - if (NormalGC(screen) != NormalBoldGC(screen)) - XtReleaseGC((Widget) xw, NormalBoldGC(screen)); - XtReleaseGC((Widget) xw, NormalGC(screen)); - - if (ReverseGC(screen) != ReverseBoldGC(screen)) - XtReleaseGC((Widget) xw, ReverseBoldGC(screen)); - XtReleaseGC((Widget) xw, ReverseGC(screen)); - - NormalGC(screen) = new_normalGC; - NormalBoldGC(screen) = new_normalboldGC; - ReverseGC(screen) = new_reverseGC; - ReverseBoldGC(screen) = new_reverseboldGC; - - /* - * If we're switching fonts, free the old ones. Otherwise we'll leak - * the memory that is associated with the old fonts. The - * XLoadQueryFont call allocates a new XFontStruct. - */ - if (screen->fnt_bold != 0 - && screen->fnt_bold != screen->fnt_norm) - XFreeFont(screen->display, screen->fnt_bold); - if (screen->fnt_norm != 0) - XFreeFont(screen->display, screen->fnt_norm); - - screen->fnt_norm = nfs; - screen->fnt_bold = bfs; -#if OPT_WIDE_CHARS - screen->fnt_dwd = wfs; - if (wbfs == NULL) - wbfs = wfs; - screen->fnt_dwdb = wbfs; -#endif - screen->fnt_prop = proportional; - screen->fnt_boxes = True; - -#if OPT_BOX_CHARS - /* - * Xterm uses character positions 1-31 of a font for the line-drawing - * characters. Check that they are all present. The null character - * (0) is special, and is not used. - */ -#if OPT_RENDERFONT - if (UsingRenderFont(xw)) { - /* - * FIXME: we shouldn't even be here if we're using Xft. - */ - screen->fnt_boxes = False; - TRACE(("assume Xft missing line-drawing chars\n")); - } else -#endif - { - unsigned ch; - - for (ch = 1; ch < 32; ch++) { - unsigned n = ch; -#if OPT_WIDE_CHARS - if (screen->utf8_mode || screen->unicode_font) { - n = dec2ucs(ch); - if (n == UCS_REPL) - continue; - } -#endif - if (xtermMissingChar(xw, n, nfs)) { - TRACE(("missing normal char #%d\n", n)); - screen->fnt_boxes = False; - break; - } - if (xtermMissingChar(xw, n, bfs)) { - TRACE(("missing bold char #%d\n", n)); - screen->fnt_boxes = False; - break; - } - } - } - TRACE(("Will %suse internal line-drawing characters\n", - screen->fnt_boxes ? "not " : "")); -#endif - - screen->enbolden = screen->bold_mode - && ((nfs == bfs) || same_font_name(normal, myfonts.f_b)); - TRACE(("Will %suse 1-pixel offset/overstrike to simulate bold\n", - screen->enbolden ? "" : "not ")); - - set_menu_font(False); - screen->menu_font_number = fontnum; - set_menu_font(True); - if (tmpname) { /* if setting escape or sel */ - if (screen->MenuFontName(fontnum)) - free(screen->MenuFontName(fontnum)); - screen->MenuFontName(fontnum) = tmpname; - if (fontnum == fontMenu_fontescape) { - set_sensitivity(xw->screen.fontMenu, - fontMenuEntries[fontMenu_fontescape].widget, - True); - } -#if OPT_SHIFT_FONTS - screen->menu_font_sizes[fontnum] = FontSize(nfs); -#endif - } - set_cursor_gcs(screen); - xtermUpdateFontInfo(xw, doresize); - return 1; - - bad: - if (tmpname) - free(tmpname); - if (new_normalGC) - XtReleaseGC((Widget) xw, new_normalGC); - if (new_normalboldGC && new_normalGC != new_normalboldGC) - XtReleaseGC((Widget) xw, new_normalboldGC); - if (new_reverseGC) - XtReleaseGC((Widget) xw, new_reverseGC); - if (new_reverseboldGC && new_reverseGC != new_reverseboldGC) - XtReleaseGC((Widget) xw, new_reverseboldGC); - if (nfs) - XFreeFont(screen->display, nfs); - if (bfs && nfs != bfs) - XFreeFont(screen->display, bfs); -#if OPT_WIDE_CHARS - if (wfs) - XFreeFont(screen->display, wfs); - if (wbfs && wbfs != wfs) - XFreeFont(screen->display, wbfs); -#endif - return 0; -} - -#if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS -/* - * Collect font-names that we can modify with the load-vt-fonts() action. - */ -typedef struct { - VTFontNames default_font; - char *menu_font_names[fontMenu_lastBuiltin + 1][fMAX]; -} SubResourceRec; - -#define MERGE_SUBFONT(src,dst,name) \ - if (dst.name == 0) { \ - TRACE(("MERGE_SUBFONT " #dst "." #name " merge %s\n", NonNull(src.name))); \ - dst.name = src.name; \ - } else { \ - TRACE(("MERGE_SUBFONT " #dst "." #name " found %s\n", NonNull(dst.name))); \ - } - -#define COPY_MENU_FONTS(src,dst) \ - TRACE(("COPY_MENU_FONTS " #src " to " #dst "\n")); \ - for (n = fontMenu_fontdefault; n <= fontMenu_lastBuiltin; ++n) { \ - for (m = 0; m < fMAX; ++m) { \ - dst.menu_font_names[n][m] = src.menu_font_names[n][m]; \ - } \ - } - -/* - * Load the "VT" font names from the given subresource name/class. These - * correspond to the VT100 resources. - */ -static Bool -xtermLoadVTFonts(XtermWidget w, char *myName, char *myClass) -{ - static Bool initialized = False; - static SubResourceRec original, referenceRec, subresourceRec; - - /* - * These are duplicates of the VT100 font resources, but with a special - * application/classname passed in to distinguish them. - */ - static XtResource font_resources[] = - { - Sres(XtNfont, XtCFont, default_font.f_n, DEFFONT), - Sres(XtNboldFont, XtCBoldFont, default_font.f_b, DEFBOLDFONT), -#if OPT_WIDE_CHARS - Sres(XtNwideFont, XtCWideFont, default_font.f_w, DEFWIDEFONT), - Sres(XtNwideBoldFont, XtCWideBoldFont, default_font.f_wb, DEFWIDEBOLDFONT), -#endif - Sres(XtNfont1, XtCFont1, MenuFontName(fontMenu_font1), NULL), - Sres(XtNfont2, XtCFont2, MenuFontName(fontMenu_font2), NULL), - Sres(XtNfont3, XtCFont3, MenuFontName(fontMenu_font3), NULL), - Sres(XtNfont4, XtCFont4, MenuFontName(fontMenu_font4), NULL), - Sres(XtNfont5, XtCFont5, MenuFontName(fontMenu_font5), NULL), - Sres(XtNfont6, XtCFont6, MenuFontName(fontMenu_font6), NULL), - }; - Cardinal n, m; - Bool status = True; - - if (!initialized) { - - initialized = True; - TRACE(("xtermLoadVTFonts saving original\n")); - original.default_font = w->misc.default_font; - COPY_MENU_FONTS(w->screen, original); - } - - if (myName == 0 || *myName == 0) { - TRACE(("xtermLoadVTFonts restoring original\n")); - w->misc.default_font = original.default_font; - COPY_MENU_FONTS(original, w->screen); - for (n = 0; n < XtNumber(original.menu_font_names); ++n) - w->screen.MenuFontName(n) = original.MenuFontName(n); - } else { - TRACE(("xtermLoadVTFonts(%s, %s)\n", myName, myClass)); - - memset(&subresourceRec, 0, sizeof(subresourceRec)); - XtGetSubresources((Widget) w, (XtPointer) &subresourceRec, - myName, myClass, - font_resources, - (Cardinal) XtNumber(font_resources), - NULL, (Cardinal) 0); - - if (memcmp(&referenceRec, &subresourceRec, sizeof(referenceRec))) { - - /* - * If a particular resource value was not found, use the original. - */ - MERGE_SUBFONT(w->misc, subresourceRec, default_font.f_n); - MERGE_SUBFONT(w->misc, subresourceRec, default_font.f_b); -#if OPT_WIDE_CHARS - MERGE_SUBFONT(w->misc, subresourceRec, default_font.f_w); - MERGE_SUBFONT(w->misc, subresourceRec, default_font.f_wb); -#endif - for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) - MERGE_SUBFONT(w->screen, subresourceRec, MenuFontName(n)); - - /* - * Finally, copy the subresource data to the widget. - */ - w->misc.default_font = subresourceRec.default_font; - COPY_MENU_FONTS(subresourceRec, w->screen); - w->screen.MenuFontName(fontMenu_fontdefault) = w->misc.default_font.f_n; - } else { - TRACE(("...no resources found\n")); - status = False; - } - } - return status; -} - -#if OPT_WIDE_CHARS -static Bool -isWideFont(XFontStruct * fp, char *tag, Bool nullOk) -{ - Bool result = False; - - (void) tag; - if (fp != 0) { - unsigned count = 0; - if (fp->min_byte1 == 0 && fp->max_byte1 == 0) { - count = fp->max_char_or_byte2 - fp->min_char_or_byte2; - } else if (fp->min_char_or_byte2 < 256 - && fp->max_char_or_byte2 < 256) { - unsigned first = (fp->min_byte1 << 8) + fp->min_char_or_byte2; - unsigned last = (fp->max_byte1 << 8) + fp->max_char_or_byte2; - count = last + 1 - first; - } - TRACE(("isWideFont(%s) found %d cells\n", tag, count)); - result = (count > 256) ? True : False; - } else { - result = nullOk; - } - return result; -} - -static Bool -currentFontsAreWide(XtermWidget w, Bool nullOk) -{ - Bool result = True; - TScreen *screen = &(w->screen); - - result = (isWideFont(screen->fnt_norm, "normal", nullOk) - && isWideFont(screen->fnt_bold, "bold", nullOk) - && isWideFont(screen->fnt_dwd, "wide", nullOk) - && isWideFont(screen->fnt_dwdb, "wide-bold", nullOk)); - - TRACE(("currentFontsAreWide returns %d\n", result)); - return result; -} - -/* - * If the current fonts are not wide, load the UTF8 fonts. - * - * Called during initialization (for wide-character mode), the fonts have not - * been setup, so we pass nullOk=True to currentFontsAreWide(). - * - * Called after initialization, e.g., in response to the UTF-8 menu entry - * (starting from narrow character mode), it checks if the fonts are not wide. - */ -Bool -xtermLoadWideFonts(XtermWidget w, Bool nullOk) -{ - Bool result = currentFontsAreWide(w, nullOk); - - /* FIXME: add a test for wide-font */ - if (!result) { - result = xtermLoadVTFonts(w, "utf8Fonts", "Utf8Fonts"); - } - TRACE(("xtermLoadWideFonts:%d\n", result)); - return result; -} -#endif /* OPT_WIDE_CHARS */ - -/* - * Restore the default fonts, i.e., if we had switched to wide-fonts. - */ -Bool -xtermLoadDefaultFonts(XtermWidget w) -{ - Bool result; - result = xtermLoadVTFonts(w, NULL, NULL); - TRACE(("xtermLoadDefaultFonts:%d\n", result)); - return result; -} -#endif /* OPT_LOAD_VTFONTS || OPT_WIDE_CHARS */ - -#if OPT_LOAD_VTFONTS -void -HandleLoadVTFonts(Widget w GCC_UNUSED, - XEvent * event GCC_UNUSED, - String * params GCC_UNUSED, - Cardinal *param_count GCC_UNUSED) -{ - static char empty[] = ""; /* appease strict compilers */ - - char buf[80]; - char *myName = (*param_count > 0) ? params[0] : empty; - char *convert = (*param_count > 1) ? params[1] : myName; - char *myClass = (char *) MyStackAlloc(strlen(convert), buf); - int n; - - TRACE(("HandleLoadVTFonts(%d)\n", *param_count)); - strcpy(myClass, convert); - if (*param_count == 1 - && islower(CharOf(myClass[0]))) - myClass[0] = toupper(CharOf(myClass[0])); - - if (xtermLoadVTFonts(term, myName, myClass)) { - /* - * When switching fonts, try to preserve the font-menu selection, since - * it is less surprising to do that (if the font-switching can be - * undone) than to switch to "Default". - */ - int font_number = term->screen.menu_font_number; - if (font_number > fontMenu_lastBuiltin) - font_number = fontMenu_lastBuiltin; - for (n = 0; n < NMENUFONTS; ++n) - term->screen.menu_font_sizes[n] = 0; - SetVTFont(term, font_number, True, - ((font_number == fontMenu_fontdefault) - ? &(term->misc.default_font) - : NULL)); - } - - MyStackFree(myClass, buf); -} -#endif /* OPT_LOAD_VTFONTS */ - -/* - * Set the limits for the box that outlines the cursor. - */ -void -xtermSetCursorBox(TScreen * screen) -{ - static XPoint VTbox[NBOX]; - XPoint *vp; - - vp = &VTbox[1]; - (vp++)->x = FontWidth(screen) - 1; - (vp++)->y = FontHeight(screen) - 1; - (vp++)->x = -(FontWidth(screen) - 1); - vp->y = -(FontHeight(screen) - 1); - screen->box = VTbox; -} - -#define CACHE_XFT(dst,src) if (src != 0) {\ - dst[fontnum] = src;\ - TRACE(("%s[%d] = %d (%d,%d) by %d\n",\ - #dst,\ - fontnum,\ - src->height,\ - src->ascent,\ - src->descent,\ - src->max_advance_width));\ - } - -#if OPT_RENDERFONT -static XftFont * -xtermOpenXft(Display * dpy, XftPattern * pat, const char *tag GCC_UNUSED) -{ - XftPattern *match; - XftResult status; - XftFont *result = 0; - - if (pat != 0) { - match = XftFontMatch(dpy, DefaultScreen(dpy), pat, &status); - result = XftFontOpenPattern(dpy, match); - if ((result == 0) && match) { - TRACE(("...did not match %s font\n", tag)); - XftPatternDestroy(match); - } else { - TRACE(("...matched %s font\n", tag)); - } - } - return result; -} -#endif - -/* - * Compute useful values for the font/window sizes - */ -void -xtermComputeFontInfo(XtermWidget xw, - struct _vtwin *win, - XFontStruct * font, - int sbwidth) -{ - TScreen *screen = &(xw->screen); - - int i, j, width, height; - -#if OPT_RENDERFONT - /* - * xterm contains a lot of references to fonts, assuming they are fixed - * size. This chunk of code overrides the actual font-selection (see - * drawXtermText()), if the user has selected render-font. All of the - * font-loading for fixed-fonts still goes on whether or not this chunk - * overrides it. - */ - if (xw->misc.render_font && !IsIconWin(screen, win)) { - Display *dpy = screen->display; - int fontnum = screen->menu_font_number; - XftFont *norm = screen->renderFontNorm[fontnum]; - XftFont *bold = screen->renderFontBold[fontnum]; - XftFont *ital = screen->renderFontItal[fontnum]; -#if OPT_RENDERWIDE - XftFont *wnorm = screen->renderWideNorm[fontnum]; - XftFont *wbold = screen->renderWideBold[fontnum]; - XftFont *wital = screen->renderWideItal[fontnum]; -#endif - - if (norm == 0 && xw->misc.face_name) { - XftPattern *pat; - double face_size = xw->misc.face_size; - - TRACE(("xtermComputeFontInfo norm(face %s, size %f)\n", - xw->misc.face_name, - xw->misc.face_size)); - -#if OPT_SHIFT_FONTS - /* - * If the user is switching font-sizes, make it follow the same - * ratios to the default as the fixed fonts would, for easy - * comparison. There will be some differences since the fixed - * fonts have a variety of height/width ratios, but this is simpler - * than adding another resource value - and as noted above, the - * data for the fixed fonts are available. - */ - lookupOneFontSize(screen, fontnum); - if (fontnum != fontMenu_fontdefault) { - int num = screen->menu_font_sizes[fontnum]; - int den = screen->menu_font_sizes[0]; - face_size = (1.0 * face_size * num) / den; - TRACE(("scaled using %d/%d -> %f\n", num, den, face_size)); - } -#endif - - pat = XftNameParse(xw->misc.face_name); - XftPatternBuild(pat, - XFT_FAMILY, XftTypeString, "mono", - XFT_SIZE, XftTypeDouble, face_size, - XFT_SPACING, XftTypeInteger, XFT_MONO, - (void *) 0); - norm = xtermOpenXft(dpy, pat, "normal"); - - if (norm != 0) { - XftPatternBuild(pat, - XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, - XFT_CHAR_WIDTH, XftTypeInteger, norm->max_advance_width, - (void *) 0); - bold = xtermOpenXft(dpy, pat, "bold"); - -#if OPT_ISO_COLORS - if (screen->italicULMode) { - XftPatternBuild(pat, - XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, - XFT_CHAR_WIDTH, XftTypeInteger, norm->max_advance_width, - (void *) 0); - ital = xtermOpenXft(dpy, pat, "italic"); - } -#endif /* OPT_ISO_COLORS */ - - /* - * FIXME: just assume that the corresponding font has no - * graphics characters. - */ - if (screen->fnt_boxes) { - screen->fnt_boxes = False; - TRACE(("Xft opened - will %suse internal line-drawing characters\n", - screen->fnt_boxes ? "not " : "")); - } - } - - if (pat) - XftPatternDestroy(pat); - - CACHE_XFT(screen->renderFontNorm, norm); - CACHE_XFT(screen->renderFontBold, bold); - CACHE_XFT(screen->renderFontItal, ital); - - /* - * See xtermXftDrawString(). - */ -#if OPT_RENDERWIDE - if (norm != 0 && screen->wide_chars) { - char *face_name = (xw->misc.face_wide_name - ? xw->misc.face_wide_name - : xw->misc.face_name); - int char_width = norm->max_advance_width * 2; - - TRACE(("xtermComputeFontInfo wide(face %s, char_width %d)\n", - face_name, - char_width)); - - pat = XftNameParse(xw->misc.face_name); - XftPatternBuild(pat, - XFT_FAMILY, XftTypeString, face_name, - XFT_SIZE, XftTypeDouble, face_size, - XFT_SPACING, XftTypeInteger, XFT_MONO, - XFT_CHAR_WIDTH, XftTypeInteger, char_width, - (void *) 0); - wnorm = xtermOpenXft(dpy, pat, "wide"); - - if (wnorm != 0) { - XftPatternBuild(pat, - XFT_FAMILY, XftTypeString, face_name, - XFT_SIZE, XftTypeDouble, face_size, - XFT_SPACING, XftTypeInteger, XFT_MONO, - XFT_CHAR_WIDTH, XftTypeInteger, char_width, - XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, - (void *) 0); - wbold = xtermOpenXft(dpy, pat, "wide-bold"); - - if (screen->italicULMode) { - XftPatternBuild(pat, - XFT_FAMILY, XftTypeString, face_name, - XFT_SIZE, XftTypeDouble, face_size, - XFT_SPACING, XftTypeInteger, XFT_MONO, - XFT_CHAR_WIDTH, XftTypeInteger, char_width, - XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, - (void *) 0); - wital = xtermOpenXft(dpy, pat, "wide-italic"); - } - } - - if (pat) - XftPatternDestroy(pat); - - CACHE_XFT(screen->renderWideNorm, wnorm); - CACHE_XFT(screen->renderWideBold, wbold); - CACHE_XFT(screen->renderWideItal, wital); - } -#endif - } - if (norm == 0) { - xw->misc.render_font = False; - update_font_renderfont(); - } else { - win->f_width = norm->max_advance_width; - win->f_height = norm->height; - win->f_ascent = norm->ascent; - win->f_descent = norm->descent; - if (win->f_height < win->f_ascent + win->f_descent) - win->f_height = win->f_ascent + win->f_descent; - if (is_double_width_font_xft(screen->display, norm)) - win->f_width >>= 1; - } - } - if (!xw->misc.render_font || IsIconWin(screen, win)) -#endif - { - if (is_double_width_font(font)) { - win->f_width = (font->min_bounds.width); - } else { - win->f_width = (font->max_bounds.width); - } - win->f_height = (font->ascent + font->descent); - win->f_ascent = font->ascent; - win->f_descent = font->descent; - } - i = 2 * screen->border + sbwidth; - j = 2 * screen->border; - width = MaxCols(screen) * win->f_width + i; - height = MaxRows(screen) * win->f_height + j; - win->fullwidth = width; - win->fullheight = height; - win->width = width - i; - win->height = height - j; - - TRACE(("xtermComputeFontInfo window %dx%d (full %dx%d), fontsize %dx%d (asc %d, dsc %d)\n", - win->height, - win->width, - win->fullheight, - win->fullwidth, - win->f_height, - win->f_width, - win->f_ascent, - win->f_descent)); -} - -/* save this information as a side-effect for double-sized characters */ -void -xtermSaveFontInfo(TScreen * screen, XFontStruct * font) -{ - screen->fnt_wide = (font->max_bounds.width); - screen->fnt_high = (font->ascent + font->descent); - TRACE(("xtermSaveFontInfo %dx%d\n", screen->fnt_high, screen->fnt_wide)); -} - -/* - * After loading a new font, update the structures that use its size. - */ -void -xtermUpdateFontInfo(XtermWidget xw, Bool doresize) -{ - TScreen *screen = &(xw->screen); - - int scrollbar_width; - struct _vtwin *win = &(screen->fullVwin); - - scrollbar_width = (xw->misc.scrollbar - ? (screen->scrollWidget->core.width + - screen->scrollWidget->core.border_width) - : 0); - xtermComputeFontInfo(xw, win, screen->fnt_norm, scrollbar_width); - xtermSaveFontInfo(screen, screen->fnt_norm); - - if (doresize) { - if (VWindow(screen)) { - XClearWindow(screen->display, VWindow(screen)); - } - TRACE(("xtermUpdateFontInfo {{\n")); - DoResizeScreen(xw); /* set to the new natural size */ - if (screen->scrollWidget) - ResizeScrollBar(xw); - Redraw(); - TRACE(("... }} xtermUpdateFontInfo\n")); -#ifdef SCROLLBAR_RIGHT - updateRightScrollbar(term); -#endif - } - xtermSetCursorBox(screen); -} - -#if OPT_BOX_CHARS - -/* - * Returns true if the given character is missing from the specified font. - */ -Bool -xtermMissingChar(XtermWidget xw, unsigned ch, XFontStruct * font) -{ - if (font != 0 - && font->per_char != 0 - && !font->all_chars_exist) { - static XCharStruct dft, *tmp = &dft, *pc = 0; - - if (font->max_byte1 == 0) { -#if OPT_WIDE_CHARS - if (ch > 255) { - TRACE(("xtermMissingChar %#04x (row)\n", ch)); - return True; - } -#endif - CI_GET_CHAR_INFO_1D(font, E2A(ch), tmp, pc); - } -#if OPT_WIDE_CHARS - else { - CI_GET_CHAR_INFO_2D(font, (ch >> 8), (ch & 0xff), tmp, pc); - } -#else - - if (!pc) - return False; /* Urgh! */ -#endif - - if (CI_NONEXISTCHAR(pc)) { - TRACE(("xtermMissingChar %#04x (!exists)\n", ch)); - return True; - } - } - if (ch < 32 - && xw->screen.force_box_chars) { - TRACE(("xtermMissingChar %#04x (forced off)\n", ch)); - return True; - } - return False; -} - -/* - * The grid is arbitrary, enough resolution that nothing's lost in - * initialization. - */ -#define BOX_HIGH 60 -#define BOX_WIDE 60 - -#define MID_HIGH (BOX_HIGH/2) -#define MID_WIDE (BOX_WIDE/2) - -#define CHR_WIDE ((9*BOX_WIDE)/10) -#define CHR_HIGH ((9*BOX_HIGH)/10) - -/* - * ...since we'll scale the values anyway. - */ -#define SCALE_X(n) n = (n * (font_width-1)) / (BOX_WIDE-1) -#define SCALE_Y(n) n = (n * (font_height-1)) / (BOX_HIGH-1) - -#define SEG(x0,y0,x1,y1) x0,y0, x1,y1 - -/* - * Draw the given graphic character, if it is simple enough (i.e., a - * line-drawing character). - */ -void -xtermDrawBoxChar(XtermWidget xw, - unsigned ch, - unsigned flags, - GC gc, - int x, - int y) -{ - TScreen *screen = &(xw->screen); - /* *INDENT-OFF* */ - static const short glyph_ht[] = { - SEG( 0, 0, 0, 5*MID_HIGH/6), /* H */ - SEG(6*BOX_WIDE/10, 0, 6*BOX_WIDE/10,5*MID_HIGH/6), - SEG( 0, 5*MID_HIGH/12,6*BOX_WIDE/10,5*MID_HIGH/12), - SEG(2*BOX_WIDE/10, MID_HIGH, CHR_WIDE, MID_HIGH), /* T */ - SEG(6*BOX_WIDE/10, MID_HIGH, 6*BOX_WIDE/10, CHR_HIGH), - -1 - }, glyph_ff[] = { - SEG( 0, 0, 6*BOX_WIDE/10, 0), /* F */ - SEG( 0, 5*MID_HIGH/12,6*CHR_WIDE/12,5*MID_HIGH/12), - SEG( 0, 0, 0*BOX_WIDE/3, 5*MID_HIGH/6), - SEG(1*BOX_WIDE/3, MID_HIGH, CHR_WIDE, MID_HIGH), /* F */ - SEG(1*BOX_WIDE/3, 8*MID_HIGH/6,10*CHR_WIDE/12,8*MID_HIGH/6), - SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), - -1 - }, glyph_lf[] = { - SEG( 0, 0, 0, 5*MID_HIGH/6), /* L */ - SEG( 0, 5*MID_HIGH/6, 6*BOX_WIDE/10,5*MID_HIGH/6), - SEG(1*BOX_WIDE/3, MID_HIGH, CHR_WIDE, MID_HIGH), /* F */ - SEG(1*BOX_WIDE/3, 8*MID_HIGH/6,10*CHR_WIDE/12,8*MID_HIGH/6), - SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), - -1 - }, glyph_nl[] = { - SEG( 0, 5*MID_HIGH/6, 0, 0), /* N */ - SEG( 0, 0, 5*BOX_WIDE/6, 5*MID_HIGH/6), - SEG(5*BOX_WIDE/6, 5*MID_HIGH/6, 5*BOX_WIDE/6, 0), - SEG(1*BOX_WIDE/3, MID_HIGH, 1*BOX_WIDE/3, CHR_HIGH), /* L */ - SEG(1*BOX_WIDE/3, CHR_HIGH, CHR_WIDE, CHR_HIGH), - -1 - }, glyph_vt[] = { - SEG( 0, 0, 5*BOX_WIDE/12,5*MID_HIGH/6), /* V */ - SEG(5*BOX_WIDE/12,5*MID_HIGH/6, 5*BOX_WIDE/6, 0), - SEG(2*BOX_WIDE/10, MID_HIGH, CHR_WIDE, MID_HIGH), /* T */ - SEG(6*BOX_WIDE/10, MID_HIGH, 6*BOX_WIDE/10, CHR_HIGH), - -1 - }, plus_or_minus[] = - { - SEG( 0, 5*BOX_HIGH/6, CHR_WIDE, 5*BOX_HIGH/6), - SEG( MID_WIDE, 2*BOX_HIGH/6, MID_WIDE, 4*BOX_HIGH/6), - SEG( 0, 3*BOX_HIGH/6, CHR_WIDE, 3*BOX_HIGH/6), - -1 - }, lower_right_corner[] = - { - SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), - SEG( MID_WIDE, MID_HIGH, MID_WIDE, 0), - -1 - }, upper_right_corner[] = - { - SEG( 0, MID_HIGH, MID_WIDE, MID_HIGH), - SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), - -1 - }, upper_left_corner[] = - { - SEG( MID_WIDE, MID_HIGH, BOX_WIDE, MID_HIGH), - SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), - -1 - }, lower_left_corner[] = - { - SEG( MID_WIDE, 0, MID_WIDE, MID_HIGH), - SEG( MID_WIDE, MID_WIDE, BOX_WIDE, MID_HIGH), - -1 - }, cross[] = - { - SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), - SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), - -1 - }, scan_line_1[] = - { - SEG( 0, 0, BOX_WIDE, 0), - -1 - }, scan_line_3[] = - { - SEG( 0, BOX_HIGH/4, BOX_WIDE, BOX_HIGH/4), - -1 - }, scan_line_7[] = - { - SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), - -1 - }, scan_line_9[] = - { - SEG( 0, 3*BOX_HIGH/4, BOX_WIDE, 3*BOX_HIGH/4), - -1 - }, horizontal_line[] = - { - SEG( 0, BOX_HIGH, BOX_WIDE, BOX_HIGH), - -1 - }, left_tee[] = - { - SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), - SEG( MID_WIDE, MID_HIGH, BOX_WIDE, MID_HIGH), - -1 - }, right_tee[] = - { - SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), - SEG( MID_WIDE, MID_HIGH, 0, MID_HIGH), - -1 - }, bottom_tee[] = - { - SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), - SEG( MID_WIDE, 0, MID_WIDE, MID_HIGH), - -1 - }, top_tee[] = - { - SEG( 0, MID_HIGH, BOX_WIDE, MID_HIGH), - SEG( MID_WIDE, MID_HIGH, MID_WIDE, BOX_HIGH), - -1 - }, vertical_line[] = - { - SEG( MID_WIDE, 0, MID_WIDE, BOX_HIGH), - -1 - }, less_than_or_equal[] = - { - SEG( CHR_WIDE, BOX_HIGH/3, 0, MID_HIGH), - SEG( CHR_WIDE, 2*BOX_HIGH/3, 0, MID_HIGH), - SEG( 0, 3*BOX_HIGH/4, CHR_WIDE, 3*BOX_HIGH/4), - -1 - }, greater_than_or_equal[] = - { - SEG( 0, BOX_HIGH/3, CHR_WIDE, MID_HIGH), - SEG( 0, 2*BOX_HIGH/3, CHR_WIDE, MID_HIGH), - SEG( 0, 3*BOX_HIGH/4, CHR_WIDE, 3*BOX_HIGH/4), - -1 - }, greek_pi[] = - { - SEG( 0, MID_HIGH, CHR_WIDE, MID_HIGH), - SEG(5*CHR_WIDE/6, MID_HIGH, 5*CHR_WIDE/6, CHR_HIGH), - SEG(2*CHR_WIDE/6, MID_HIGH, 2*CHR_WIDE/6, CHR_HIGH), - -1 - }, not_equal_to[] = - { - SEG(2*BOX_WIDE/3, 1*BOX_HIGH/3, 1*BOX_WIDE/3, CHR_HIGH), - SEG( 0, 2*BOX_HIGH/3, CHR_WIDE, 2*BOX_HIGH/3), - SEG( 0, MID_HIGH, CHR_WIDE, MID_HIGH), - -1 - }; - /* *INDENT-ON* */ - - static const short *lines[] = - { - 0, /* 00 (unused) */ - 0, /* 01 diamond */ - 0, /* 02 box */ - glyph_ht, /* 03 HT */ - glyph_ff, /* 04 FF */ - 0, /* 05 CR */ - glyph_lf, /* 06 LF */ - 0, /* 07 degrees (small circle) */ - plus_or_minus, /* 08 */ - glyph_nl, /* 09 */ - glyph_vt, /* 0A */ - lower_right_corner, /* 0B */ - upper_right_corner, /* 0C */ - upper_left_corner, /* 0D */ - lower_left_corner, /* 0E */ - cross, /* 0F */ - scan_line_1, /* 10 */ - scan_line_3, /* 11 */ - scan_line_7, /* 12 */ - scan_line_9, /* 13 */ - horizontal_line, /* 14 */ - left_tee, /* 15 */ - right_tee, /* 16 */ - bottom_tee, /* 17 */ - top_tee, /* 18 */ - vertical_line, /* 19 */ - less_than_or_equal, /* 1A */ - greater_than_or_equal, /* 1B */ - greek_pi, /* 1C */ - not_equal_to, /* 1D */ - 0, /* 1E LB */ - 0, /* 1F bullet */ - }; - - XGCValues values; - unsigned long mask; - GC gc2; - const short *p; - unsigned font_width = ((flags & DOUBLEWFONT) ? 2 : 1) * screen->fnt_wide; - unsigned font_height = ((flags & DOUBLEHFONT) ? 2 : 1) * screen->fnt_high; - -#if OPT_WIDE_CHARS - /* - * Try to show line-drawing characters if we happen to be in UTF-8 - * mode, but have gotten an old-style font. - */ - if (screen->utf8_mode -#if OPT_RENDERFONT - && !UsingRenderFont(xw) -#endif - && (ch > 127) - && (ch != UCS_REPL)) { - unsigned n; - for (n = 1; n < 32; n++) { - if (dec2ucs(n) == ch - && !xtermMissingChar(xw, n, (flags & BOLD) - ? screen->fnt_bold - : screen->fnt_norm)) { - TRACE(("...use xterm-style linedrawing\n")); - ch = n; - break; - } - } - } -#endif - - TRACE(("DRAW_BOX(%d) cell %dx%d at %d,%d%s\n", - ch, font_height, font_width, y, x, - (ch >= (sizeof(lines) / sizeof(lines[0])) - ? "-BAD" - : ""))); - - if (!XGetGCValues(screen->display, gc, GCBackground, &values)) - return; - - mask = GCForeground; - if (ch == 2) { - values.tile = - XmuCreateStippledPixmap(XtScreen((Widget) xw), - getXtermForeground(xw->flags, xw->cur_foreground), - getXtermBackground(xw->flags, xw->cur_background), - xw->core.depth); - if (values.stipple != XtUnspecifiedPixmap) { - mask |= GCBackground | GCTile | GCFillStyle; - values.fill_style = FillTiled; - } else { - ch = (unsigned) (~0); /* make this not match anything */ - } - } else { - values.foreground = values.background; - } - gc2 = XCreateGC(screen->display, - VWindow(screen), - mask, - &values); - - if (!(flags & NOBACKGROUND)) { - XFillRectangle(screen->display, VWindow(screen), gc2, x, y, - font_width, - font_height); - } - - XCopyGC(screen->display, gc, (1 << GCLastBit) - 1, gc2); - XSetLineAttributes(screen->display, gc2, - (flags & BOLD) - ? ((font_height > 12) - ? font_height / 12 - : 1) - : ((font_height > 16) - ? font_height / 16 - : 1), - LineSolid, - CapProjecting, - JoinMiter); - - if (ch == 1) { /* diamond */ - XPoint points[5]; - int npoints = 5, n; - - points[0].x = MID_WIDE; - points[0].y = BOX_HIGH / 4; - - points[1].x = 3 * BOX_WIDE / 4; - points[1].y = MID_HIGH; - - points[2].x = points[0].x; - points[2].y = 3 * BOX_HIGH / 4; - - points[3].x = BOX_WIDE / 4; - points[3].y = points[1].y; - - points[4].x = points[0].x; - points[4].y = points[0].y; - - for (n = 0; n < npoints; ++n) { - SCALE_X(points[n].x); - SCALE_Y(points[n].y); - points[n].x += x; - points[n].y += y; - } - - XFillPolygon(screen->display, - VWindow(screen), gc2, - points, npoints, - Convex, CoordModeOrigin); - } else if (ch == 2) { /* box */ - XmuReleaseStippledPixmap(XtScreen((Widget) xw), values.tile); - } else if (ch == 7) { /* degrees */ - unsigned width = (BOX_WIDE / 3); - int x_coord = MID_WIDE - (width / 2); - int y_coord = MID_HIGH - width; - - SCALE_X(x_coord); - SCALE_Y(y_coord); - SCALE_X(width); - - XDrawArc(screen->display, - VWindow(screen), gc2, - x + x_coord, y + y_coord, width, width, - 0, - 360 * 64); - } else if (ch == 0x1f) { /* bullet */ - unsigned width = 7 * BOX_WIDE / 10; - int x_coord = MID_WIDE - (width / 3); - int y_coord = MID_HIGH - (width / 3); - - SCALE_X(x_coord); - SCALE_Y(y_coord); - SCALE_X(width); - - XFillArc(screen->display, - VWindow(screen), gc2, - x + x_coord, y + y_coord, width, width, - 0, - 360 * 64); - } else if (ch < (sizeof(lines) / sizeof(lines[0])) - && (p = lines[ch]) != 0) { - int coord[4]; - int n = 0; - while (*p >= 0) { - coord[n++] = *p++; - if (n == 4) { - SCALE_X(coord[0]); - SCALE_Y(coord[1]); - SCALE_X(coord[2]); - SCALE_Y(coord[3]); - XDrawLine(screen->display, - VWindow(screen), gc2, - x + coord[0], y + coord[1], - x + coord[2], y + coord[3]); - n = 0; - } - } - } else if (screen->force_all_chars) { - /* bounding rectangle, for debugging */ - XDrawRectangle(screen->display, VWindow(screen), gc2, x, y, - font_width - 1, - font_height - 1); - } - - XFreeGC(screen->display, gc2); -} - -#if OPT_RENDERFONT && OPT_WIDE_CHARS - -/* - * Check if the given character has a glyph known to Xft. - * - * see xc/lib/Xft/xftglyphs.c - */ -Bool -xtermXftMissing(XtermWidget xw, XftFont * font, unsigned wc) -{ - unsigned check = XftCharIndex(xw->screen.display, font, wc); - Bool result = False; - - if (check == 0) { - TRACE(("missingXft %d (%d)\n", wc, ucs2dec(wc))); - result = True; - } - return result; -} - -/* - * Check if the character corresponds to one of xterm's internal codes for - * line-drawing characters. That is only a subset of the 1-31 codes used for - * graphic characters. We want to know specifically about the line-drawing - * characters because the fonts used by Xft do not always give useful glyphs - * for line-drawing, and there is no reliable way to detect this. - */ -Bool -xtermIsLineDrawing(unsigned wc) -{ - Bool result; - switch (wc) { - case 0x0B: /* lower_right_corner */ - case 0x0C: /* upper_right_corner */ - case 0x0D: /* upper_left_corner */ - case 0x0E: /* lower_left_corner */ - case 0x0F: /* cross */ - case 0x10: /* scan_line_1 */ - case 0x11: /* scan_line_3 */ - case 0x12: /* scan_line_7 */ - case 0x13: /* scan_line_9 */ - case 0x14: /* horizontal_line */ - case 0x15: /* left_tee */ - case 0x16: /* right_tee */ - case 0x17: /* bottom_tee */ - case 0x18: /* top_tee */ - case 0x19: /* vertical_line */ - result = True; - TRACE(("xtermIsLineDrawing %d\n", wc)); - break; - default: - result = False; - break; - } - return result; -} -#endif /* OPT_RENDERFONT && OPT_WIDE_CHARS */ - -#endif /* OPT_BOX_CHARS */ - -#if OPT_WIDE_CHARS -#define MY_UCS(ucs,dec) case ucs: result = dec; break -unsigned -ucs2dec(unsigned ch) -{ - unsigned result = ch; - if ((ch > 127) - && (ch != UCS_REPL)) { - switch (ch) { - MY_UCS(0x25ae, 0); /* black vertical rectangle */ - MY_UCS(0x25c6, 1); /* black diamond */ - MY_UCS(0x2592, 2); /* medium shade */ - MY_UCS(0x2409, 3); /* symbol for horizontal tabulation */ - MY_UCS(0x240c, 4); /* symbol for form feed */ - MY_UCS(0x240d, 5); /* symbol for carriage return */ - MY_UCS(0x240a, 6); /* symbol for line feed */ - MY_UCS(0x00b0, 7); /* degree sign */ - MY_UCS(0x00b1, 8); /* plus-minus sign */ - MY_UCS(0x2424, 9); /* symbol for newline */ - MY_UCS(0x240b, 10); /* symbol for vertical tabulation */ - MY_UCS(0x2518, 11); /* box drawings light up and left */ - MY_UCS(0x2510, 12); /* box drawings light down and left */ - MY_UCS(0x250c, 13); /* box drawings light down and right */ - MY_UCS(0x2514, 14); /* box drawings light up and right */ - MY_UCS(0x253c, 15); /* box drawings light vertical and horizontal */ - MY_UCS(0x23ba, 16); /* box drawings scan 1 */ - MY_UCS(0x23bb, 17); /* box drawings scan 3 */ - MY_UCS(0x2500, 18); /* box drawings light horizontal */ - MY_UCS(0x23bc, 19); /* box drawings scan 7 */ - MY_UCS(0x23bd, 20); /* box drawings scan 9 */ - MY_UCS(0x251c, 21); /* box drawings light vertical and right */ - MY_UCS(0x2524, 22); /* box drawings light vertical and left */ - MY_UCS(0x2534, 23); /* box drawings light up and horizontal */ - MY_UCS(0x252c, 24); /* box drawings light down and horizontal */ - MY_UCS(0x2502, 25); /* box drawings light vertical */ - MY_UCS(0x2264, 26); /* less-than or equal to */ - MY_UCS(0x2265, 27); /* greater-than or equal to */ - MY_UCS(0x03c0, 28); /* greek small letter pi */ - MY_UCS(0x2260, 29); /* not equal to */ - MY_UCS(0x00a3, 30); /* pound sign */ - MY_UCS(0x00b7, 31); /* middle dot */ - } - } - return result; -} - -#undef MY_UCS -#define MY_UCS(ucs,dec) case dec: result = ucs; break - -unsigned -dec2ucs(unsigned ch) -{ - unsigned result = ch; - if (ch < 32) { - switch (ch) { - MY_UCS(0x25ae, 0); /* black vertical rectangle */ - MY_UCS(0x25c6, 1); /* black diamond */ - MY_UCS(0x2592, 2); /* medium shade */ - MY_UCS(0x2409, 3); /* symbol for horizontal tabulation */ - MY_UCS(0x240c, 4); /* symbol for form feed */ - MY_UCS(0x240d, 5); /* symbol for carriage return */ - MY_UCS(0x240a, 6); /* symbol for line feed */ - MY_UCS(0x00b0, 7); /* degree sign */ - MY_UCS(0x00b1, 8); /* plus-minus sign */ - MY_UCS(0x2424, 9); /* symbol for newline */ - MY_UCS(0x240b, 10); /* symbol for vertical tabulation */ - MY_UCS(0x2518, 11); /* box drawings light up and left */ - MY_UCS(0x2510, 12); /* box drawings light down and left */ - MY_UCS(0x250c, 13); /* box drawings light down and right */ - MY_UCS(0x2514, 14); /* box drawings light up and right */ - MY_UCS(0x253c, 15); /* box drawings light vertical and horizontal */ - MY_UCS(0x23ba, 16); /* box drawings scan 1 */ - MY_UCS(0x23bb, 17); /* box drawings scan 3 */ - MY_UCS(0x2500, 18); /* box drawings light horizontal */ - MY_UCS(0x23bc, 19); /* box drawings scan 7 */ - MY_UCS(0x23bd, 20); /* box drawings scan 9 */ - MY_UCS(0x251c, 21); /* box drawings light vertical and right */ - MY_UCS(0x2524, 22); /* box drawings light vertical and left */ - MY_UCS(0x2534, 23); /* box drawings light up and horizontal */ - MY_UCS(0x252c, 24); /* box drawings light down and horizontal */ - MY_UCS(0x2502, 25); /* box drawings light vertical */ - MY_UCS(0x2264, 26); /* less-than or equal to */ - MY_UCS(0x2265, 27); /* greater-than or equal to */ - MY_UCS(0x03c0, 28); /* greek small letter pi */ - MY_UCS(0x2260, 29); /* not equal to */ - MY_UCS(0x00a3, 30); /* pound sign */ - MY_UCS(0x00b7, 31); /* middle dot */ - } - } - return result; -} - -#endif /* OPT_WIDE_CHARS */ - -#if OPT_SHIFT_FONTS -static XFontStruct * -xtermFindFont(TScreen * screen, int fontnum) -{ - XFontStruct *nfs = 0; - char *name; - - if ((name = screen->MenuFontName(fontnum)) != 0 - && (nfs = XLoadQueryFont(screen->display, name)) != 0) { - if (EmptyFont(nfs)) { - XFreeFont(screen->display, nfs); - nfs = 0; - } - } - return nfs; -} - -static void -lookupOneFontSize(TScreen * screen, int fontnum) -{ - if (screen->menu_font_sizes[fontnum] == 0) { - XFontStruct *fs = xtermFindFont(screen, fontnum); - screen->menu_font_sizes[fontnum] = -1; - if (fs != 0) { - screen->menu_font_sizes[fontnum] = FontSize(fs); - TRACE(("menu_font_sizes[%d] = %ld\n", fontnum, - screen->menu_font_sizes[fontnum])); - XFreeFont(screen->display, fs); - } - } -} - -/* - * Cache the font-sizes so subsequent larger/smaller font actions will go fast. - */ -static void -lookupFontSizes(TScreen * screen) -{ - int n; - - for (n = 0; n < NMENUFONTS; n++) { - lookupOneFontSize(screen, n); - } -} - -/* - * Find the index of a larger/smaller font (according to the sign of 'relative' - * and its magnitude), starting from the 'old' index. - */ -int -lookupRelativeFontSize(TScreen * screen, int old, int relative) -{ - int n, m = -1; - - if (!IsIcon(screen)) { - lookupFontSizes(screen); - if (relative != 0) { - for (n = 0; n < NMENUFONTS; ++n) { - if (screen->menu_font_sizes[n] > 0 && - screen->menu_font_sizes[n] != screen->menu_font_sizes[old]) { - int cmp_0 = ((screen->menu_font_sizes[n] > - screen->menu_font_sizes[old]) - ? relative - : -relative); - int cmp_m = ((m < 0) - ? 1 - : ((screen->menu_font_sizes[n] < - screen->menu_font_sizes[m]) - ? relative - : -relative)); - if (cmp_0 > 0 && cmp_m > 0) { - m = n; - } - } - } - if (m >= 0) { - if (relative > 1) - m = lookupRelativeFontSize(screen, m, relative - 1); - else if (relative < -1) - m = lookupRelativeFontSize(screen, m, relative + 1); - } - } - } - return m; -} - -/* ARGSUSED */ -void -HandleLargerFont(Widget w GCC_UNUSED, - XEvent * event GCC_UNUSED, - String * params GCC_UNUSED, - Cardinal *param_count GCC_UNUSED) -{ - if (term->misc.shift_fonts) { - TScreen *screen = &term->screen; - int m; - - m = lookupRelativeFontSize(screen, screen->menu_font_number, 1); - if (m >= 0) { - SetVTFont(term, m, True, NULL); - } else { - Bell(XkbBI_MinorError, 0); - } - } -} - -/* ARGSUSED */ -void -HandleSmallerFont(Widget w GCC_UNUSED, - XEvent * event GCC_UNUSED, - String * params GCC_UNUSED, - Cardinal *param_count GCC_UNUSED) -{ - if (term->misc.shift_fonts) { - TScreen *screen = &term->screen; - int m; - - m = lookupRelativeFontSize(screen, screen->menu_font_number, -1); - if (m >= 0) { - SetVTFont(term, m, True, NULL); - } else { - Bell(XkbBI_MinorError, 0); - } - } -} -#endif - -/* ARGSUSED */ -void -HandleSetFont(Widget w GCC_UNUSED, - XEvent * event GCC_UNUSED, - String * params, - Cardinal *param_count) -{ - int fontnum; - VTFontNames fonts; - - memset(&fonts, 0, sizeof(fonts)); - - if (*param_count == 0) { - fontnum = fontMenu_fontdefault; - } else { - Cardinal maxparams = 1; /* total number of params allowed */ - - switch (params[0][0]) { - case 'd': - case 'D': - case '0': - fontnum = fontMenu_fontdefault; - break; - case '1': - fontnum = fontMenu_font1; - break; - case '2': - fontnum = fontMenu_font2; - break; - case '3': - fontnum = fontMenu_font3; - break; - case '4': - fontnum = fontMenu_font4; - break; - case '5': - fontnum = fontMenu_font5; - break; - case '6': - fontnum = fontMenu_font6; - break; - case 'e': - case 'E': - fontnum = fontMenu_fontescape; -#if OPT_WIDE_CHARS - maxparams = 5; -#else - maxparams = 3; -#endif - break; - case 's': - case 'S': - fontnum = fontMenu_fontsel; - maxparams = 2; - break; - default: - Bell(XkbBI_MinorError, 0); - return; - } - if (*param_count > maxparams) { /* see if extra args given */ - Bell(XkbBI_MinorError, 0); - return; - } - switch (*param_count) { /* assign 'em */ -#if OPT_WIDE_CHARS - case 5: - fonts.f_wb = params[4]; - /* FALLTHRU */ - case 4: - fonts.f_w = params[3]; - /* FALLTHRU */ -#endif - case 3: - fonts.f_b = params[2]; - /* FALLTHRU */ - case 2: - fonts.f_n = params[1]; - break; - } - } - - SetVTFont(term, fontnum, True, &fonts); -} - -void -SetVTFont(XtermWidget xw, - int which, - Bool doresize, - const VTFontNames * fonts) -{ - TScreen *screen = &xw->screen; - - TRACE(("SetVTFont(which=%d, f_n=%s, f_b=%s)\n", which, - (fonts && fonts->f_n) ? fonts->f_n : "<null>", - (fonts && fonts->f_b) ? fonts->f_b : "<null>")); - - if (IsIcon(screen)) { - Bell(XkbBI_MinorError, 0); - } else if (which >= 0 && which < NMENUFONTS) { - VTFontNames myfonts; - - memset(&myfonts, 0, sizeof(myfonts)); - if (fonts != 0) - myfonts = *fonts; - - if (which == fontMenu_fontsel) { /* go get the selection */ - FindFontSelection(myfonts.f_n, False); - return; - } else { - if (myfonts.f_n == 0) { - myfonts.f_n = screen->MenuFontName(which); - TRACE(("set myfonts.f_n from menu_font_names[%d][fNorm] %s\n", - which, NonNull(myfonts.f_n))); - } - if (myfonts.f_b == 0) { - myfonts.f_b = screen->menu_font_names[which][fBold]; - TRACE(("set myfonts.f_b from menu_font_names[%d][fBold] %s\n", - which, NonNull(myfonts.f_b))); - } -#if OPT_WIDE_CHARS - if (myfonts.f_w == 0) { - myfonts.f_w = screen->menu_font_names[which][fWide]; - TRACE(("set myfonts.f_w from menu_font_names[%d][fWide] %s\n", - which, NonNull(myfonts.f_w))); - } - if (myfonts.f_wb == 0) { - myfonts.f_wb = screen->menu_font_names[which][fWBold]; - TRACE(("set myfonts.f_wb from menu_font_names[%d][fWBold] %s\n", - which, NonNull(myfonts.f_wb))); - } -#endif - if (xtermLoadFont(xw, - &myfonts, - doresize, which)) { - return; - } - } - } - - Bell(XkbBI_MinorError, 0); - return; -} |