aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/xterm/fontutils.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
commitb16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 (patch)
tree4361edef0d42d5bf5ac984ef72b4fac35426eae7 /nx-X11/programs/xterm/fontutils.c
parent0d5a83e986f39982c0924652a3662e60b1f23162 (diff)
downloadnx-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.c2371
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;
-}