Tue Sep 21 20:00:50 PDT 1999 Michael Jennings <mej@eterm.org>

Initial work on font caching.  WARNING:  This code is broken and will
	not compile, but I'm going home anyway.


SVN revision: 362
This commit is contained in:
Michael Jennings 1999-09-22 02:34:13 +00:00
parent bbb476846f
commit f3c6a56ace
12 changed files with 515 additions and 312 deletions

View File

@ -2444,6 +2444,12 @@ Mon Sep 20 21:25:46 PDT 1999 Michael Jennings <mej@eterm.org>
Added support for xterm's property change escape sequence as requested
by Greg Badros <gjb@cs.washington.edu>, the originator of the
sequence.
sequence (and one of the authors of scwm).
-------------------------------------------------------------------------------
Tue Sep 21 20:00:50 PDT 1999 Michael Jennings <mej@eterm.org>
Initial work on font caching. WARNING: This code is broken and will
not compile, but I'm going home anyway.
-------------------------------------------------------------------------------

View File

@ -2,7 +2,7 @@
lib_LTLIBRARIES = libEterm.la
libEterm_la_SOURCES = actions.c command.c e.c events.c graphics.c grkelot.c menus.c misc.c netdisp.c \
libEterm_la_SOURCES = actions.c command.c e.c events.c font.c graphics.c grkelot.c menus.c misc.c netdisp.c \
options.c pixmap.c screen.c scrollbar.c system.c term.c threads.c timer.c utmp.c windows.c
libEterm_la_DEPENDENCIES = $(top_builddir)/libmej/libmej.la feature.h
libEterm_la_LDFLAGS = -version-info 9:0:9
@ -15,6 +15,6 @@ Eterm_LDFLAGS = -rpath $(libdir):$(pkglibdir)
INCLUDES = -I. -I$(top_srcdir)/libmej -I.. -I$(includedir) -I$(prefix)/include $(X_CFLAGS)
LDADD = libEterm.la $(top_builddir)/libmej/libmej.la -L$(libdir) -L$(prefix)/lib $(LIBS) $(GRLIBS) $(X_LIBS)
EXTRA_DIST = actions.h command.h debug.h e.h eterm_utmp.h events.h feature.h graphics.h grkelot.h grx.h main.h menus.h misc.h \
EXTRA_DIST = actions.h command.h debug.h e.h eterm_utmp.h events.h feature.h font.h graphics.h grkelot.h grx.h main.h menus.h misc.h \
options.h pixmap.h profile.h screen.h scrollbar.h system.h term.h threads.h timer.h windows.h graphics/Makefile.am \
graphics/Makefile.in graphics/README graphics/data graphics/grxlib.c graphics/grxlib.h graphics/qplot.c Eterm.xpm

View File

@ -26,12 +26,20 @@ extern unsigned int debug_level;
# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \
else {print_warning("ASSERT failed at %s:%d: %s", __FILE__, __LINE__, #x);} \
return (val);}} while (0)
# define ASSERT_NOTREACHED() do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
} while (0)
# define ASSERT_NOTREACHED_RVAL(val) do {if (debug_level>=1) {fatal_error("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
else {print_warning("ASSERT failed at %s:%d: This code should not be reached.", __FILE__, __LINE__);} \
return (val);} while (0)
# define ABORT() fatal_error("Aborting at %s:%d.", __FILE__, __LINE__)
#else
# define ASSERT(x) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \
else {print_warning("ASSERT failed: %s", #x);}}} while (0)
# define ASSERT_RVAL(x, val) do {if (!(x)) {if (debug_level>=1) {fatal_error("ASSERT failed: %s", #x);} \
else {print_warning("ASSERT failed: %s", #x);} return (val);}} while (0)
# define ASSERT_NOTREACHED() return
# define ASSERT_NOTREACHED_RVAL(x) return (x)
# define ABORT() fatal_error("Aborting.")
#endif
@ -41,6 +49,7 @@ extern unsigned int debug_level;
#define REQUIRE(x) do {if (!(x)) {if (debug_level>=1) {__DEBUG(); real_dprintf("REQUIRE failed: %s\n", #x);} return;}} while (0)
#define REQUIRE_RVAL(x, v) do {if (!(x)) {if (debug_level>=1) {__DEBUG(); real_dprintf("REQUIRE failed: %s\n", #x);} return (v);}} while (0)
#define NONULL(x) ((x) ? (x) : ("<null>"))
/* Macros for printing debugging messages */
# if DEBUG >= 1
@ -102,6 +111,8 @@ extern unsigned int debug_level;
# define DEBUG_MENU 3
# define D_MENU(x) DPRINTF3(x)
# define DEBUG_FONT 3
# define D_FONT(x) DPRINTF3(x)
# define DEBUG_TTYMODE 3
# define D_TTYMODE(x) DPRINTF3(x)
# define DEBUG_COLORS 3

View File

@ -284,11 +284,11 @@
# undef GREEK_SUPPORT
# undef XTERM_FONT_CHANGE
# undef DEFINE_XTERM_COLOR
# define KFONT0 "k14"
# define KFONT1 "jiskan16"
# define KFONT2 "jiskan18"
# define KFONT3 "jiskan24"
# define KFONT4 "jiskan26"
# define MFONT0 "k14"
# define MFONT1 "jiskan16"
# define MFONT2 "jiskan18"
# define MFONT3 "jiskan24"
# define MFONT4 "jiskan26"
/* sizes matched to multichar fonts */
# define FONT0 "fixed"
# define FONT1 "8x16"

383
src/font.c Normal file
View File

@ -0,0 +1,383 @@
/* font.c -- Eterm font module
*
* This file is original work by Michael Jennings <mej@eterm.org> and
* Tuomo Venalainen <vendu@cc.hut.fi>. This file, and any other file
* bearing this same message or a similar one, is distributed under
* the GNU Public License (GPL) as outlined in the COPYING file.
*
* Copyright (C) 1997, Michael Jennings and Tuomo Venalainen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
static const char cvs_ident[] = "$Id$";
#include "config.h"
#include "feature.h"
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include "../libmej/debug.h"
#include "../libmej/mem.h"
#include "../libmej/strings.h"
#include "debug.h"
#include "command.h"
#include "font.h"
#include "main.h"
#include "options.h"
#include "screen.h"
#include "term.h"
#include "windows.h"
#undef D_FONT
#define D_FONT(x) do {__DEBUG(); real_dprintf x;} while (0)
unsigned char font_change_count = 0;
#ifdef MULTI_CHARSET
const char *def_mfontName[] = {MFONT0, MFONT1, MFONT2, MFONT3, MFONT4};
#endif
const char *def_fontName[] = {FONT0, FONT1, FONT2, FONT3, FONT4};
static etfont_t *font_cache = NULL, *cur_font = NULL;
static void font_cache_add(const char *name, unsigned char type, void *info);
static void font_cache_del(const void *info);
static etfont_t *font_cache_find(const char *name, unsigned char type);
static void
font_cache_add(const char *name, unsigned char type, void *info) {
etfont_t *font;
D_FONT(("font_cache_add(%s, %d, 0x%08x) called.\n", NONULL(name), type, (int) info));
font = (etfont_t *) MALLOC(sizeof(etfont_t));
font->name = StrDup(name);
font->type = type;
font->ref_cnt = 1;
switch (type) {
case FONT_TYPE_X: font->fontinfo.xfontinfo = (XFontStruct *) info; break;
case FONT_TYPE_TTF: break;
case FONT_TYPE_FNLIB: break;
default: break;
}
if (font_cache == NULL) {
font_cache = cur_font = font;
font->next = NULL;
} else {
cur_font->next = font;
font->next = NULL;
cur_font = font;
}
}
static void
font_cache_del(const void *info) {
etfont_t *current, *tmp;
D_FONT(("font_cache_del(0x%08x) called.\n", (int) info));
if (font_cache == NULL) {
return;
}
if (((font_cache->type == FONT_TYPE_X) && (font_cache->fontinfo.xfontinfo == (XFontStruct *) info))) {
D_FONT((" -> Match found at font_cache (0x%08x).\n", (int) font_cache));
if (--(font_cache->ref_cnt) == 0) {
D_FONT((" -> Reference count is now 0. Deleting from cache.\n"));
current = font_cache;
font_cache = current->next;
XFreeFont(Xdisplay, (XFontStruct *) info);
FREE(current->name);
FREE(current);
} else {
D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
}
return;
} else if ((font_cache->type == FONT_TYPE_TTF) && (0)) {
} else if ((font_cache->type == FONT_TYPE_FNLIB) && (0)) {
} else {
for (current = font_cache; current->next; current = current->next) {
if (((current->next->type == FONT_TYPE_X) && (current->next->fontinfo.xfontinfo == (XFontStruct *) info))) {
D_FONT((" -> Match found at current->next (0x%08x, current == 0x%08x).\n", (int) current->next, (int) current));
if (--(current->next->ref_cnt) == 0) {
D_FONT((" -> Reference count is now 0. Deleting from cache.\n"));
tmp = current->next;
current->next = current->next->next;
XFreeFont(Xdisplay, (XFontStruct *) info);
FREE(tmp->name);
FREE(tmp);
} else {
D_FONT((" -> Reference count is %d. Returning.\n", font_cache->ref_cnt));
}
return;
} else if ((current->next->type == FONT_TYPE_TTF) && (0)) {
} else if ((current->next->type == FONT_TYPE_FNLIB) && (0)) {
}
}
}
}
static etfont_t *
font_cache_find(const char *name, unsigned char type) {
etfont_t *current;
ASSERT_RVAL(name != NULL, NULL);
D_FONT(("font_cache_find(%s, %d) called.\n", NONULL(name), type));
for (current = font_cache; current; current = current->next) {
D_FONT((" -> Checking current (0x%08x), type == %d, name == %s\n", current, type, NONULL(name)));
if ((current->type == type) && !strcasecmp(current->name, name)) {
D_FONT((" -> Match!\n"));
return (current);
}
}
D_FONT(("font_cache_find(): No matches found. =(\n"));
return ((etfont_t *) NULL);
}
#error This code is broken. Try again tomorrow.
void *
load_font(const char *name, const char *fallback, unsigned char type)
{
etfont_t *font;
XFontStruct *xfont;
if (type == 0) {
type = FONT_TYPE_X;
}
if (name == NULL) {
if (fallback) {
name = fallback;
fallback = "fixed";
} else {
name = "fixed";
fallback = "-misc-fixed-medium-r-normal--13-120-75-75-c-60-iso8859-1";
}
} else if (fallback == NULL) {
fallback = "fixed";
}
if ((font = font_cache_find(name, type)) != NULL) {
font_cache_add_ref(font);
switch (type) {
case FONT_TYPE_X: return ((void *) font->fontinfo.xfontinfo); break;
case FONT_TYPE_TTF: return (NULL); break;
case FONT_TYPE_FNLIB: return (NULL); break;
default: return (NULL); break;
}
}
if (type == FONT_TYPE_X) {
if ((xfont = XLoadQueryFont(Xdisplay, name)) == NULL) {
print_error("Unable to load font \"%s\". Falling back on \"%s\"\n", name, fallback);
if ((xfont = XLoadQueryFont(Xdisplay, fallback)) == NULL) {
fatal_error("Couldn't load the fallback font either. Giving up.");
} else {
font_cache_add(fallback, type, (void *) xfont);
}
} else {
font_cache_add(name, type, (void *) xfont);
}
return ((void *) xfont);
} else if (type == FONT_TYPE_TTF) {
return (NULL);
} else if (type == FONT_TYPE_FNLIB) {
return (NULL);
}
ASSERT_NOTREACHED_RVAL(NULL);
}
void
free_font(const void *info)
{
ASSERT(info != NULL);
font_cache_del(info);
}
void
change_font(int init, const char *fontname)
{
XFontStruct *xfont;
#ifndef NO_BOLDFONT
static XFontStruct *boldFont = NULL;
#endif
static short fnum = FONT0_IDX;
short idx = 0;
if (!init) {
ASSERT(fontname != NULL);
switch (fontname[0]) {
case '\0':
fnum = FONT0_IDX;
fontname = NULL;
break;
/* special (internal) prefix for font commands */
case FONT_CMD:
idx = atoi(fontname + 1);
switch (fontname[1]) {
case '+': /* corresponds to FONT_UP */
fnum += (idx ? idx : 1);
fnum = FNUM_RANGE(fnum);
break;
case '-': /* corresponds to FONT_DN */
fnum += (idx ? idx : -1);
fnum = FNUM_RANGE(fnum);
break;
default:
if (fontname[1] != '\0' && !isdigit(fontname[1]))
return;
if (idx < 0 || idx >= (NFONTS))
return;
fnum = IDX2FNUM(idx);
break;
}
fontname = NULL;
break;
default:
if (fontname != NULL) {
/* search for existing fontname */
for (idx = 0; idx < NFONTS; idx++) {
if (!strcmp(rs_font[idx], fontname)) {
fnum = IDX2FNUM(idx);
fontname = NULL;
break;
}
}
} else
return;
break;
}
idx = FNUM2IDX(fnum);
RESET_AND_ASSIGN(rs_font[idx], fontname);
}
if (TermWin.font) {
free_font(TermWin.font);
}
TermWin.font = load_font(rs_font[idx], "fixed", FONT_TYPE_X);
#ifndef NO_BOLDFONT
if (init && rs_boldFont != NULL) {
boldFont = load_font(rs_boldFont, "-misc-fixed-bold-r-semicondensed--13-120-75-75-c-60-iso8859-1", FONT_TYPE_X);
}
#endif
#ifdef MULTI_CHARSET
if (TermWin.mfont) {
free_font(TermWin.mfont);
}
TermWin.mfont = load_font(rs_mfont[idx], "k14", FONT_TYPE_X);
# ifdef USE_XIM
if (Input_Context) {
if (TermWin.fontset) {
XFreeFontSet(Xdisplay, TermWin.fontset);
}
TermWin.fontset = create_fontset(rs_font[idx], rs_mfont[idx]);
xim_set_fontset();
}
# endif
#endif /* MULTI_CHARSET */
/* alter existing GC */
if (!init) {
XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid);
}
/* set the sizes */
{
int cw, fh, fw = 0;
unsigned long i;
fw = TermWin.font->min_bounds.width;
fh = TermWin.font->ascent + TermWin.font->descent + rs_line_space;
D_X11(("Font information: Ascent == %hd, Descent == %hd\n", TermWin.font->ascent, TermWin.font->descent));
if (TermWin.font->min_bounds.width == TermWin.font->max_bounds.width)
TermWin.fprop = 0; /* Mono-spaced (fixed width) font */
else
TermWin.fprop = 1; /* Proportional font */
if (TermWin.fprop == 1)
for (i = TermWin.font->min_char_or_byte2;
i <= TermWin.font->max_char_or_byte2; i++) {
cw = TermWin.font->per_char[i].width;
MAX_IT(fw, cw);
}
/* not the first time thru and sizes haven't changed */
if (fw == TermWin.fwidth && fh == TermWin.fheight)
return; /* TODO: not return; check MULTI_CHARSET if needed */
TermWin.fwidth = fw;
TermWin.fheight = fh;
}
/* check that size of boldFont is okay */
#ifndef NO_BOLDFONT
TermWin.boldFont = NULL;
if (boldFont != NULL) {
int i, cw, fh, fw = 0;
fw = boldFont->min_bounds.width;
fh = boldFont->ascent + boldFont->descent + rs_line_space;
if (TermWin.fprop == 0) { /* bold font must also be monospaced */
if (fw != boldFont->max_bounds.width)
fw = -1;
} else {
for (i = 0; i < 256; i++) {
if (!isprint(i))
continue;
cw = boldFont->per_char[i].width;
MAX_IT(fw, cw);
}
}
if (fw == TermWin.fwidth && fh == TermWin.fheight)
TermWin.boldFont = boldFont;
}
#endif /* NO_BOLDFONT */
set_colorfgbg();
TermWin.width = TermWin.ncol * TermWin.fwidth;
TermWin.height = TermWin.nrow * TermWin.fheight;
szHint.width_inc = TermWin.fwidth;
szHint.height_inc = TermWin.fheight;
szHint.min_width = szHint.base_width + szHint.width_inc;
szHint.min_height = szHint.base_height + szHint.height_inc;
szHint.width = szHint.base_width + TermWin.width;
szHint.height = szHint.base_height + TermWin.height;
szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;
if (!init) {
font_change_count++;
resize();
}
return;
}

83
src/font.h Normal file
View File

@ -0,0 +1,83 @@
/* font.h -- Eterm font module header file
*
* This file is original work by Michael Jennings <mej@eterm.org> and
* Tuomo Venalainen <vendu@cc.hut.fi>. This file, and any other file
* bearing this same message or a similar one, is distributed under
* the GNU Public License (GPL) as outlined in the COPYING file.
*
* Copyright (C) 1997, Michael Jennings and Tuomo Venalainen
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef _FONT_H_
#define _FONT_H_
#include <stdio.h>
#include <X11/Xfuncproto.h>
#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */
/************ Macros and Definitions ************/
#define FONT_TYPE_X (0x01)
#define FONT_TYPE_TTF (0x02)
#define FONT_TYPE_FNLIB (0x03)
#define font_cache_add_ref(font) ((font)->ref_cnt++)
# define NFONTS 5
/* special (internal) prefix for font commands */
# define FONT_CMD '#'
# define FONT_DN "#-"
# define FONT_UP "#+"
#if (FONT0_IDX == 0)
# define IDX2FNUM(i) (i)
# define FNUM2IDX(f) (f)
#else
# define IDX2FNUM(i) (i == 0? FONT0_IDX : (i <= FONT0_IDX? (i-1) : i))
# define FNUM2IDX(f) (f == FONT0_IDX ? 0 : (f < FONT0_IDX ? (f+1) : f))
#endif
#define FNUM_RANGE(i) (i <= 0 ? 0 : (i >= NFONTS ? (NFONTS-1) : i))
/************ Structures ************/
typedef struct font_struct {
char *name;
unsigned char type;
unsigned char ref_cnt;
union {
XFontStruct *xfontinfo;
} fontinfo;
struct font_struct *next;
} etfont_t;
/************ Variables ************/
extern unsigned char font_change_count;
extern const char *def_fontName[];
extern const char *rs_font[NFONTS];
# ifdef MULTI_CHARSET
extern const char *def_mfontName[];
extern const char *rs_mfont[NFONTS];
# endif
/************ Function Prototypes ************/
_XFUNCPROTOBEGIN
extern void *load_font(const char *, const char *, unsigned char);
extern void free_font(const void *);
extern void change_font(int, const char *);
_XFUNCPROTOEND
#endif /* _FONT_H_ */

View File

@ -35,6 +35,7 @@ static const char cvs_ident[] = "$Id$";
#include "../libmej/strings.h"
#include "command.h"
#include "events.h"
#include "font.h"
#include "main.h"
#include "menus.h"
#include "misc.h"
@ -447,7 +448,7 @@ menu_set_font(menu_t * menu, const char *fontname)
ASSERT_RVAL(menu != NULL, 0);
ASSERT_RVAL(fontname != NULL, 0);
font = load_font(fontname);
font = (XFontStruct *) load_font(fontname, "fixed", FONT_TYPE_X);
#ifdef MULTI_CHARSET
menu->fontset = create_fontset(fontname, rs_mfont[0]);
#endif

View File

@ -48,6 +48,7 @@ static const char cvs_ident[] = "$Id$";
#include "actions.h"
#include "command.h"
#include "events.h"
#include "font.h"
#include "grkelot.h"
#include "main.h"
#include "menus.h"
@ -3311,11 +3312,12 @@ post_parse(void)
}
#endif
for (i = 0; i < NFONTS; i++) {
if (!rs_font[i])
rs_font[i] = def_fontName[i];
if (!rs_font[i]) {
rs_font[i] = StrDup(def_fontName[i]);
}
#ifdef MULTI_CHARSET
if (!rs_mfont[i]) {
rs_mfont[i] = def_kfontName[i];
rs_mfont[i] = StrDup(def_mfontName[i]);
}
#endif
}

View File

@ -1,5 +1,5 @@
/* term.c -- Eterm terminal emulation module
*
* This file is original work by Michael Jennings <mej@eterm.org> and
* Tuomo Venalainen <vendu@cc.hut.fi>. This file, and any other file
* bearing this same message or a similar one, is distributed under
@ -41,6 +41,7 @@ static const char cvs_ident[] = "$Id$";
#include "command.h"
#include "e.h"
#include "events.h"
#include "font.h"
#include "main.h"
#include "options.h"
#include "pixmap.h"

View File

@ -41,6 +41,7 @@ static const char cvs_ident[] = "$Id$";
#include "command.h"
#include "e.h"
#include "events.h"
#include "font.h"
#include "main.h"
#include "menus.h"
#include "options.h"
@ -64,18 +65,6 @@ XSizeHints szHint =
0, 0, /* base size: width, height */
NorthWestGravity /* gravity */
};
int font_change_count = 0;
#ifdef MULTI_CHARSET
/* Kanji font names, roman fonts sized to match */
const char *def_kfontName[] =
{
KFONT0, KFONT1, KFONT2, KFONT3, KFONT4
};
#endif /* MULTI_CHARSET */
const char *def_fontName[] =
{
FONT0, FONT1, FONT2, FONT3, FONT4
};
Cursor TermWin_cursor; /* cursor for vt window */
void
@ -662,51 +651,36 @@ set_window_color(int idx, const char *color)
i -= 8;
# ifndef NO_BRIGHTCOLOR
PixColors[idx] = PixColors[minBright + i];
goto Done;
# endif
}
# ifndef NO_BRIGHTCOLOR
else
# endif
if (i >= 0 && i <= 7) { /* normal colors */
PixColors[idx] = PixColors[minColor + i];
goto Done;
} else {
print_warning("Color index %d is invalid.", i);
return;
}
}
if (XParseColor(Xdisplay, cmap, color, &xcol)) {
} else if (XParseColor(Xdisplay, cmap, color, &xcol)) {
r = xcol.red;
g = xcol.green;
b = xcol.blue;
pixel = Imlib_best_color_match(imlib_id, &r, &g, &b);
xcol.pixel = pixel;
if (!XAllocColor(Xdisplay, cmap, &xcol)) {
print_warning("Unable to allocate \"%s\" in the color map.\n", color);
print_warning("Unable to allocate \"%s\" in the color map.", color);
return;
}
} else {
print_warning("Unable to resolve \"%s\" as a color name.\n", color);
return;
}
/*
* FIXME: should free colors here, but no idea how to do it so instead,
* so just keep gobbling up the colormap
*/
# if 0
for (i = BlackColor; i <= WhiteColor; i++)
if (PixColors[idx] == PixColors[i])
break;
if (i > WhiteColor) {
/* fprintf (stderr, "XFreeColors: PixColors[%d] = %lu\n", idx, PixColors[idx]); */
XFreeColors(Xdisplay, cmap, (PixColors + idx), 1,
DisplayPlanes(Xdisplay, Xscreen));
}
# endif
PixColors[idx] = xcol.pixel;
} else {
print_warning("Unable to resolve \"%s\" as a color name.", color);
return;
}
/* XSetWindowAttributes attr; */
/* Cursor cursor; */
Done:
if (idx == bgColor)
if (idx == bgColor) {
XSetWindowBackground(Xdisplay, TermWin.vt, PixColors[bgColor]);
}
/* handle colorBD, scrollbar background, etc. */
@ -729,239 +703,3 @@ Done:
# define set_window_color(idx,color) ((void)0)
#endif /* XTERM_COLOR_CHANGE */
/* load_font(): Load a new font and return a pointer to it. */
XFontStruct *
load_font(const char *fontname)
{
XFontStruct *xfont;
const char *fallback = "fixed";
ASSERT_RVAL(fontname != NULL, NULL);
xfont = XLoadQueryFont(Xdisplay, fontname);
if (!xfont) {
print_error("Unable to load font \"%s\". Falling back on \"%s\"\n", fontname, fallback);
xfont = XLoadQueryFont(Xdisplay, fallback);
if (!xfont) {
fatal_error("Unable to load font \"%s\". Unable to continue.\n", fallback);
}
}
return (xfont);
}
/* change_font() - Switch to a new font */
/*
* init = 1 - initialize
*
* fontname == FONT_UP - switch to bigger font
* fontname == FONT_DN - switch to smaller font
*/
void
change_font(int init, const char *fontname)
{
const char *const msg = "can't load font \"%s\"";
XFontStruct *xfont;
static char *newfont[NFONTS];
#ifndef NO_BOLDFONT
static XFontStruct *boldFont = NULL;
#endif
static int fnum = FONT0_IDX; /* logical font number */
int idx = 0; /* index into rs_font[] */
if (!init) {
switch (fontname[0]) {
case '\0':
fnum = FONT0_IDX;
fontname = NULL;
break;
/* special (internal) prefix for font commands */
case FONT_CMD:
idx = atoi(fontname + 1);
switch (fontname[1]) {
case '+': /* corresponds to FONT_UP */
fnum += (idx ? idx : 1);
fnum = FNUM_RANGE(fnum);
break;
case '-': /* corresponds to FONT_DN */
fnum += (idx ? idx : -1);
fnum = FNUM_RANGE(fnum);
break;
default:
if (fontname[1] != '\0' && !isdigit(fontname[1]))
return;
if (idx < 0 || idx >= (NFONTS))
return;
fnum = IDX2FNUM(idx);
break;
}
fontname = NULL;
break;
default:
if (fontname != NULL) {
/* search for existing fontname */
for (idx = 0; idx < NFONTS; idx++) {
if (!strcmp(rs_font[idx], fontname)) {
fnum = IDX2FNUM(idx);
fontname = NULL;
break;
}
}
} else
return;
break;
}
/* re-position around the normal font */
idx = FNUM2IDX(fnum);
if (fontname != NULL) {
char *name;
xfont = XLoadQueryFont(Xdisplay, fontname);
if (!xfont)
return;
name = MALLOC(strlen(fontname + 1) * sizeof(char));
if (name == NULL) {
XFreeFont(Xdisplay, xfont);
return;
}
strcpy(name, fontname);
if (newfont[idx] != NULL)
FREE(newfont[idx]);
newfont[idx] = name;
rs_font[idx] = newfont[idx];
}
}
if (TermWin.font)
XFreeFont(Xdisplay, TermWin.font);
/* load font or substitute */
xfont = XLoadQueryFont(Xdisplay, rs_font[idx]);
if (!xfont) {
print_error(msg, rs_font[idx]);
rs_font[idx] = "fixed";
xfont = XLoadQueryFont(Xdisplay, rs_font[idx]);
if (!xfont) {
print_error(msg, rs_font[idx]);
ABORT();
}
}
TermWin.font = xfont;
#ifndef NO_BOLDFONT
/* fail silently */
if (init && rs_boldFont != NULL)
boldFont = XLoadQueryFont(Xdisplay, rs_boldFont);
#endif
#ifdef MULTI_CHARSET
if (TermWin.mfont)
XFreeFont(Xdisplay, TermWin.mfont);
/* load font or substitute */
xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]);
if (!xfont) {
print_error(msg, rs_mfont[idx]);
rs_mfont[idx] = "k14";
xfont = XLoadQueryFont(Xdisplay, rs_mfont[idx]);
if (!xfont) {
print_error(msg, rs_mfont[idx]);
ABORT();
}
}
TermWin.mfont = xfont;
# ifdef USE_XIM
if (Input_Context) {
if (TermWin.fontset)
XFreeFontSet(Xdisplay, TermWin.fontset);
TermWin.fontset = create_fontset(rs_font[idx], rs_mfont[idx]);
xim_set_fontset();
}
# endif
#endif /* MULTI_CHARSET */
/* alter existing GC */
if (!init) {
XSetFont(Xdisplay, TermWin.gc, TermWin.font->fid);
}
/* set the sizes */
{
int cw, fh, fw = 0;
unsigned long i;
fw = TermWin.font->min_bounds.width;
fh = TermWin.font->ascent + TermWin.font->descent + rs_line_space;
D_X11(("Font information: Ascent == %hd, Descent == %hd\n", TermWin.font->ascent, TermWin.font->descent));
if (TermWin.font->min_bounds.width == TermWin.font->max_bounds.width)
TermWin.fprop = 0; /* Mono-spaced (fixed width) font */
else
TermWin.fprop = 1; /* Proportional font */
if (TermWin.fprop == 1)
for (i = TermWin.font->min_char_or_byte2;
i <= TermWin.font->max_char_or_byte2; i++) {
cw = TermWin.font->per_char[i].width;
MAX_IT(fw, cw);
}
/* not the first time thru and sizes haven't changed */
if (fw == TermWin.fwidth && fh == TermWin.fheight)
return; /* TODO: not return; check MULTI_CHARSET if needed */
TermWin.fwidth = fw;
TermWin.fheight = fh;
}
/* check that size of boldFont is okay */
#ifndef NO_BOLDFONT
TermWin.boldFont = NULL;
if (boldFont != NULL) {
int i, cw, fh, fw = 0;
fw = boldFont->min_bounds.width;
fh = boldFont->ascent + boldFont->descent + rs_line_space;
if (TermWin.fprop == 0) { /* bold font must also be monospaced */
if (fw != boldFont->max_bounds.width)
fw = -1;
} else {
for (i = 0; i < 256; i++) {
if (!isprint(i))
continue;
cw = boldFont->per_char[i].width;
MAX_IT(fw, cw);
}
}
if (fw == TermWin.fwidth && fh == TermWin.fheight)
TermWin.boldFont = boldFont;
}
#endif /* NO_BOLDFONT */
set_colorfgbg();
TermWin.width = TermWin.ncol * TermWin.fwidth;
TermWin.height = TermWin.nrow * TermWin.fheight;
szHint.width_inc = TermWin.fwidth;
szHint.height_inc = TermWin.fheight;
szHint.min_width = szHint.base_width + szHint.width_inc;
szHint.min_height = szHint.base_height + szHint.height_inc;
szHint.width = szHint.base_width + TermWin.width;
szHint.height = szHint.base_height + TermWin.height;
szHint.flags = PMinSize | PResizeInc | PBaseSize | PWinGravity;
if (!init) {
font_change_count++;
resize();
}
return;
}

View File

@ -31,19 +31,6 @@
#include <X11/Intrinsic.h> /* Xlib, Xutil, Xresource, Xfuncproto */
/************ Macros and Definitions ************/
# define NFONTS 5
/* special (internal) prefix for font commands */
# define FONT_CMD '#'
# define FONT_DN "#-"
# define FONT_UP "#+"
#if (FONT0_IDX == 0)
# define IDX2FNUM(i) (i)
# define FNUM2IDX(f) (f)
#else
# define IDX2FNUM(i) (i == 0? FONT0_IDX : (i <= FONT0_IDX? (i-1) : i))
# define FNUM2IDX(f) (f == FONT0_IDX ? 0 : (f < FONT0_IDX ? (f+1) : f))
#endif
#define FNUM_RANGE(i) (i <= 0 ? 0 : (i >= NFONTS ? (NFONTS-1) : i))
/************ Variables ************/
extern char *rs_color[NRS_COLORS];
@ -51,13 +38,6 @@ extern Pixel PixColors[NRS_COLORS + NSHADOWCOLORS];
extern XSetWindowAttributes Attributes;
extern XWindowAttributes attr;
extern XSizeHints szHint;
extern int font_change_count;
extern const char *def_fontName[];
extern const char *rs_font[NFONTS];
# ifdef MULTI_CHARSET
extern const char *def_kfontName[];
extern const char *rs_mfont[NFONTS];
# endif
/************ Function Prototypes ************/
_XFUNCPROTOBEGIN
@ -76,8 +56,6 @@ extern void set_window_color(int, const char *);
#else
# define set_window_color(idx,color) ((void)0)
#endif /* XTERM_COLOR_CHANGE */
extern XFontStruct *load_font(const char *);
extern void change_font(int, const char *);
_XFUNCPROTOEND