From f3c6a56ace612febcef35386d2d37487bbf8fc51 Mon Sep 17 00:00:00 2001 From: Michael Jennings Date: Wed, 22 Sep 1999 02:34:13 +0000 Subject: [PATCH] Tue Sep 21 20:00:50 PDT 1999 Michael Jennings Initial work on font caching. WARNING: This code is broken and will not compile, but I'm going home anyway. SVN revision: 362 --- ChangeLog | 8 +- src/Makefile.am | 4 +- src/debug.h | 11 ++ src/feature.h | 10 +- src/font.c | 383 ++++++++++++++++++++++++++++++++++++++++++++++++ src/font.h | 83 +++++++++++ src/menus.c | 3 +- src/options.c | 8 +- src/term.c | 5 +- src/term.h | 2 +- src/windows.c | 288 ++---------------------------------- src/windows.h | 22 --- 12 files changed, 515 insertions(+), 312 deletions(-) create mode 100644 src/font.c create mode 100644 src/font.h diff --git a/ChangeLog b/ChangeLog index e4bc07d..6dbd6a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2444,6 +2444,12 @@ Mon Sep 20 21:25:46 PDT 1999 Michael Jennings Added support for xterm's property change escape sequence as requested by Greg Badros , the originator of the - sequence. + sequence (and one of the authors of scwm). + +------------------------------------------------------------------------------- +Tue Sep 21 20:00:50 PDT 1999 Michael Jennings + + Initial work on font caching. WARNING: This code is broken and will + not compile, but I'm going home anyway. ------------------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index 0131196..63493bd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 diff --git a/src/debug.h b/src/debug.h index 286fc7b..c8d7d97 100644 --- a/src/debug.h +++ b/src/debug.h @@ -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) : ("")) /* 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 diff --git a/src/feature.h b/src/feature.h index ee059ff..85a7629 100644 --- a/src/feature.h +++ b/src/feature.h @@ -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" diff --git a/src/font.c b/src/font.c new file mode 100644 index 0000000..0049fdd --- /dev/null +++ b/src/font.c @@ -0,0 +1,383 @@ +/* font.c -- Eterm font module + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . 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 +#include +#include +#include + +#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; +} diff --git a/src/font.h b/src/font.h new file mode 100644 index 0000000..b42dfbd --- /dev/null +++ b/src/font.h @@ -0,0 +1,83 @@ +/* font.h -- Eterm font module header file + * + * This file is original work by Michael Jennings and + * Tuomo Venalainen . 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 +#include +#include /* 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_ */ diff --git a/src/menus.c b/src/menus.c index 0bf2fc1..fc55065 100644 --- a/src/menus.c +++ b/src/menus.c @@ -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 diff --git a/src/options.c b/src/options.c index 8bfb713..d9b16e5 100644 --- a/src/options.c +++ b/src/options.c @@ -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 } diff --git a/src/term.c b/src/term.c index 4e5e7fa..3cfc22f 100644 --- a/src/term.c +++ b/src/term.c @@ -1,5 +1,5 @@ -/* term.c -- Eterm terminal emulation module - +/* term.c -- Eterm terminal emulation module + * * This file is original work by Michael Jennings and * Tuomo Venalainen . 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" diff --git a/src/term.h b/src/term.h index 8470982..4bf725c 100644 --- a/src/term.h +++ b/src/term.h @@ -1,4 +1,4 @@ -/* term.h -- Eterm terminal emulation module header file +/* term.h -- Eterm terminal emulation module header file * * This file is original work by Michael Jennings and * Tuomo Venalainen . This file, and any other file diff --git a/src/windows.c b/src/windows.c index d490b44..32deb99 100644 --- a/src/windows.c +++ b/src/windows.c @@ -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; } + PixColors[idx] = xcol.pixel; } else { - print_warning("Unable to resolve \"%s\" as a color name.\n", color); + print_warning("Unable to resolve \"%s\" as a color name.", 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; - - /* 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; -} diff --git a/src/windows.h b/src/windows.h index 38a3ef9..281b65b 100644 --- a/src/windows.h +++ b/src/windows.h @@ -31,19 +31,6 @@ #include /* 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