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:
parent
bbb476846f
commit
f3c6a56ace
|
@ -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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
11
src/debug.h
11
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) : ("<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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* term.c -- Eterm terminal emulation module
|
||||
|
||||
/* 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"
|
||||
|
|
|
@ -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 <mej@eterm.org> and
|
||||
* Tuomo Venalainen <vendu@cc.hut.fi>. This file, and any other file
|
||||
|
|
288
src/windows.c
288
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue