Fri May 26 20:43:03 PDT 2000 Michael Jennings <mej@eterm.org>

Okay, there are a few changes here.  First off, I made multi-byte font
	support the default now, as long as you have ISO 10646 fonts.  In
	order to do this, I made the default encoding type "Latin1" so as not
	to interfere with 8-bit ISO 8859-1 characters.  This means that if you
	relied on the default multi-byte encoding method to be SJIS, you'll
	need to update your theme files.

	I also set it up so that Eterm will ignore SIGHUP, at least until I do
	something with it (like reloading the theme or something).

	I fixed the proportional font size algorithm.  If there is more than
	a 3-pixel variance between the minimum and maximum sizes for glyphs in
	a proportional font, Eterm will set the size to 2 standard deviations
	above the average width.  This is so that they won't look so spread
	out and ugly, but it still doesn't look perfect.  Not much I can do on
	that front...terminals must have fixed-width columns.

	And then there's the biggie.  I put in the ability to configure the
	now-infamous font effects.  I left a black drop shadow in as the
	default, but you can now customize it via the --font-fx option or in
	the config file using "font effects <stuff>" in the attributes
	context.  You can even use "fx" instead of "effects" for short.

	So what goes in the <stuff> part?  Well, you have several options.
	To use a single-color outline, say "outline <color>".  Likewise, a
	single-color drop shadow is "shadow [corner] <color>"; "bottom_right"
	is the default corner if you don't specify one.  For a 3-D embossed
	look, "emboss <dark_color> <light_color>".  The opposite, a carved-
	out look, can be had with "carved <dark_color> <light_color>".  (Of
	course, with those last two, the 3-D look will only work if you
	choose the colors wisely.)

	Those are all the shortcuts.  The long way is to specify a series of
	corner/color pairs, like "tl blue" for top-left blue, or
	"bottom_right green".  You can abbreviate using "tl," "tr," "bl," or
	"br," or you can spell out "top_left," "top_right," "bottom_left," or
	"bottom_right."  If you omit a corner name, the first one defaults to
	top-left, the second to top-right, and so on as listed above.


SVN revision: 2714
This commit is contained in:
Michael Jennings 2000-05-27 03:41:22 +00:00
parent 970728fcce
commit e64307644d
13 changed files with 510 additions and 152 deletions

View File

@ -3560,3 +3560,45 @@ Thu May 4 00:32:45 PDT 2000 Michael Jennings <mej@eterm.org>
to be faster than the old stuff, probably by quite a bit.
-------------------------------------------------------------------------------
Fri May 26 20:43:03 PDT 2000 Michael Jennings <mej@eterm.org>
Okay, there are a few changes here. First off, I made multi-byte font
support the default now, as long as you have ISO 10646 fonts. In
order to do this, I made the default encoding type "Latin1" so as not
to interfere with 8-bit ISO 8859-1 characters. This means that if you
relied on the default multi-byte encoding method to be SJIS, you'll
need to update your theme files.
I also set it up so that Eterm will ignore SIGHUP, at least until I do
something with it (like reloading the theme or something).
I fixed the proportional font size algorithm. If there is more than
a 3-pixel variance between the minimum and maximum sizes for glyphs in
a proportional font, Eterm will set the size to 2 standard deviations
above the average width. This is so that they won't look so spread
out and ugly, but it still doesn't look perfect. Not much I can do on
that front...terminals must have fixed-width columns.
And then there's the biggie. I put in the ability to configure the
now-infamous font effects. I left a black drop shadow in as the
default, but you can now customize it via the --font-fx option or in
the config file using "font effects <stuff>" in the attributes
context. You can even use "fx" instead of "effects" for short.
So what goes in the <stuff> part? Well, you have several options.
To use a single-color outline, say "outline <color>". Likewise, a
single-color drop shadow is "shadow [corner] <color>"; "bottom_right"
is the default corner if you don't specify one. For a 3-D embossed
look, "emboss <dark_color> <light_color>". The opposite, a carved-
out look, can be had with "carved <dark_color> <light_color>". (Of
course, with those last two, the 3-D look will only work if you
choose the colors wisely.)
Those are all the shortcuts. The long way is to specify a series of
corner/color pairs, like "tl blue" for top-left blue, or
"bottom_right green". You can abbreviate using "tl," "tr," "bl," or
"br," or you can spell out "top_left," "top_right," "bottom_left," or
"bottom_right." If you omit a corner name, the first one defaults to
top-left, the second to top-right, and so on as listed above.
-------------------------------------------------------------------------------

View File

@ -424,76 +424,84 @@ AC_ARG_WITH(end,
MULTICHAR_ENCODING=""
AC_MSG_CHECKING(for multi-charset support)
AC_ARG_ENABLE(multi-charset,
[ --enable-multi-charset compile with multi-charset support],
if test "$enableval" = "yes" -o "$enableval" = "kanji"; then
AC_MSG_RESULT(kanji)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=0
MULTICHAR_ENCODING="eucj"
FONT0="fixed"
FONT1="8x16"
FONT2="9x18"
FONT3="12x24"
FONT4="13x26"
MFONT0="k14"
MFONT1="jiskan16"
MFONT2="jiskan18"
MFONT3="jiskan24"
MFONT4="jiskan26"
elif test "$enableval" = "euc-kr" -o "$enableval" = "euckr"; then
AC_MSG_RESULT(euckr)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=1
MULTICHAR_ENCODING="euckr"
FONT0="7x14"
FONT1="8x16"
FONT2="9x18"
FONT3="10x20"
FONT4="12x24"
MFONT0="-*-gulim-medium-r-normal--14-*-*-*-*-140-ksc5601.1987-0"
MFONT1="-*-gulim-medium-r-normal--16-*-*-*-*-160-ksc5601.1987-0"
MFONT2="-*-gulim-medium-r-normal--18-*-*-*-*-180-ksc5601.1987-0"
MFONT3="-*-gulim-medium-r-normal--20-*-*-*-*-200-ksc5601.1987-0"
MFONT4="-*-gulim-medium-r-normal--24-*-*-*-*-240-ksc5601.1987-0"
elif test "$enableval" = "utf-8" -o "$enableval" = "utf8"; then
AC_MSG_RESULT(utf-8)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=2
MULTICHAR_ENCODING="utf8"
MFONT0="-misc-fixed-medium-r-normal--7-70-75-75-c-50-iso10646-1"
MFONT1="-misc-fixed-medium-r-normal--10-100-75-75-c-60-iso10646-1"
MFONT2="-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"
MFONT3="-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso10646-1"
MFONT4="-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1"
FONT0="5x7"
FONT1="6x10"
FONT2="fixed"
FONT3="8x13"
FONT4="9x15"
elif test "$enableval" = "no"; then
AC_MSG_RESULT(no)
DEF_FONT_IDX=2
FONT0="5x7"
FONT1="6x10"
FONT2="fixed"
FONT3="8x13"
FONT4="9x15"
[ --enable-multi-charset compile with multibyte font support],
if test "$enableval" = "no"; then
MULTI_CHARSET_TYPE=""
else
AC_ERROR(invalid value for --enable-multi-charset)
fi, AC_MSG_RESULT(no)
DEF_FONT_IDX=2
MULTICHAR_ENCODING=none
MFONT0=none
MFONT1=none
MFONT2=none
MFONT3=none
MFONT4=none
FONT0="5x7"
FONT1="6x10"
FONT2="fixed"
FONT3="8x13"
FONT4="9x15"
)
MULTI_CHARSET_TYPE="$enableval"
fi,
if (xlsfonts | grep 10646 >/dev/null 2>&1); then
MULTI_CHARSET_TYPE="unicode"
else
MULTI_CHARSET_TYPE=""
fi
)
if test "x$MULTI_CHARSET_TYPE" != "x"; then
if test "$MULTI_CHARSET_TYPE" = "kanji"; then
AC_MSG_RESULT(kanji)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=0
MULTICHAR_ENCODING="eucj"
FONT0="fixed"
FONT1="8x16"
FONT2="9x18"
FONT3="12x24"
FONT4="13x26"
MFONT0="k14"
MFONT1="jiskan16"
MFONT2="jiskan18"
MFONT3="jiskan24"
MFONT4="jiskan26"
elif test "$MULTI_CHARSET_TYPE" = "euc-kr" -o "$MULTI_CHARSET_TYPE" = "euckr"; then
AC_MSG_RESULT(euckr)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=1
MULTICHAR_ENCODING="euckr"
FONT0="7x14"
FONT1="8x16"
FONT2="9x18"
FONT3="10x20"
FONT4="12x24"
MFONT0="-*-gulim-medium-r-normal--14-*-*-*-*-140-ksc5601.1987-0"
MFONT1="-*-gulim-medium-r-normal--16-*-*-*-*-160-ksc5601.1987-0"
MFONT2="-*-gulim-medium-r-normal--18-*-*-*-*-180-ksc5601.1987-0"
MFONT3="-*-gulim-medium-r-normal--20-*-*-*-*-200-ksc5601.1987-0"
MFONT4="-*-gulim-medium-r-normal--24-*-*-*-*-240-ksc5601.1987-0"
elif test "$MULTI_CHARSET_TYPE" = "unicode" -o "$MULTI_CHARSET_TYPE" = "utf-8" -o "$MULTI_CHARSET_TYPE" = "utf8"; then
AC_MSG_RESULT(ISO-10646)
AC_DEFINE(MULTI_CHARSET)
DEF_FONT_IDX=2
MULTICHAR_ENCODING="iso-10646"
MFONT0="-misc-fixed-medium-r-normal--7-70-75-75-c-50-iso10646-1"
MFONT1="-misc-fixed-medium-r-normal--10-100-75-75-c-60-iso10646-1"
MFONT2="-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1"
MFONT3="-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso10646-1"
MFONT4="-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1"
FONT0="5x7"
FONT1="6x10"
FONT2="fixed"
FONT3="8x13"
FONT4="9x15"
else
MULTI_CHARSET_TYPE=""
fi
fi
if test "x$MULTI_CHARSET_TYPE" = "x"; then
AC_MSG_RESULT(no)
DEF_FONT_IDX=2
MULTICHAR_ENCODING=none
MFONT0=none
MFONT1=none
MFONT2=none
MFONT3=none
MFONT4=none
FONT0="5x7"
FONT1="6x10"
FONT2="fixed"
FONT3="8x13"
FONT4="9x15"
fi
AC_DEFINE_UNQUOTED(DEF_FONT_IDX, $DEF_FONT_IDX)
AC_DEFINE_UNQUOTED(FONT0, "$FONT0")

View File

@ -240,10 +240,10 @@ Word(unsigned long index, const char *str)
/* Return pointer into str to index-th word in str. "..." counts as 1 word. */
char *
PWord(unsigned long index, char *str)
PWord(unsigned long index, const char *str)
{
register char *tmpstr = str;
register const char *tmpstr = str;
register unsigned long j;
if (!str)
@ -262,7 +262,7 @@ PWord(unsigned long index, char *str)
return ((char *) NULL);
} else {
D_STRINGS(("PWord(%lu, %s) returning \"%s\"\n", index, str, tmpstr));
return tmpstr;
return (char *) tmpstr;
}
}

View File

@ -75,7 +75,7 @@ extern char *RightStr(const char *, unsigned long);
extern unsigned char Match(const char *, const char *);
#endif
extern char *Word(unsigned long, const char *);
extern char *PWord(unsigned long, char *);
extern char *PWord(unsigned long, const char *);
extern unsigned long NumWords(const char *);
extern char *StripWhitespace(char *);
extern char *LowerStr(char *);

View File

@ -1090,25 +1090,23 @@ handle_crash(int sig)
void
install_handlers(void)
{
signal(SIGHUP, handle_exit_signal);
/* Ignore SIGHUP */
/* signal(SIGHUP, handle_exit_signal); */
#ifndef __svr4__
signal(SIGINT, handle_exit_signal);
signal(SIGINT, handle_exit_signal);
#endif
signal(SIGQUIT, handle_crash);
signal(SIGTERM, handle_exit_signal);
signal(SIGCHLD, handle_child_signal);
signal(SIGQUIT, handle_crash);
signal(SIGSEGV, handle_crash);
signal(SIGBUS, handle_crash);
signal(SIGBUS, handle_crash);
signal(SIGABRT, handle_crash);
signal(SIGFPE, handle_crash);
signal(SIGILL, handle_crash);
signal(SIGSYS, handle_crash);
signal(SIGFPE, handle_crash);
signal(SIGILL, handle_crash);
signal(SIGSYS, handle_crash);
}
/*
* Exit gracefully, clearing the utmp entry and restoring tty attributes
* TODO: Also free up X resources, etc., if possible
*/
/* Exit gracefully, clearing the utmp entry and restoring tty attributes */
void
clean_exit(void)
{

View File

@ -30,6 +30,7 @@ static const char cvs_ident[] = "$Id$";
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <math.h>
#include "../libmej/debug.h"
#include "../libmej/mem.h"
@ -53,12 +54,14 @@ const char *def_mfontName[] = {MFONT0, MFONT1, MFONT2, MFONT3, MFONT4};
#endif
const char *def_fontName[] = {FONT0, FONT1, FONT2, FONT3, FONT4};
unsigned char font_chg = 0;
fontshadow_t fshadow = { { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, 1 };
static cachefont_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 cachefont_t *font_cache_find(const char *name, unsigned char type);
static void *font_cache_find_info(const char *name, unsigned char type);
static unsigned char get_corner(const char *corner);
void
eterm_font_add(char ***plist, const char *fontname, unsigned char idx) {
@ -427,20 +430,45 @@ change_font(int init, const char *fontname)
fw = TermWin.font->min_bounds.width;
fh = TermWin.font->ascent + TermWin.font->descent + rs_line_space;
D_FONT(("Font information: Ascent == %hd, Descent == %hd\n", TermWin.font->ascent, TermWin.font->descent));
D_FONT(("Font information: Ascent == %hd, Descent == %hd, width min/max %d/%d\n", TermWin.font->ascent, TermWin.font->descent,
TermWin.font->min_bounds.width, TermWin.font->max_bounds.width));
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 */
LOWER_BOUND(fw, TermWin.font->max_bounds.width);
if (TermWin.fprop) {
fw = (fw << 1) / 3;
if (TermWin.fprop && TermWin.font->per_char && (TermWin.font->max_bounds.width - TermWin.font->min_bounds.width >= 3)) {
int cw, n = 0, sum = 0, sumsq = 0, min_w, max_w;
unsigned int i;
double dev;
min_w = fw;
max_w = TermWin.font->max_bounds.width;
for (i = TermWin.font->min_char_or_byte2; i <= TermWin.font->max_char_or_byte2; i++) {
cw = TermWin.font->per_char[i].width;
if (cw >= min_w && cw <= max_w) {
sum += cw;
sumsq += (cw * cw);
n++;
}
}
if (n) {
dev = sqrt((sumsq - (sum * sum) / n) / n);
/* Final font width is the average width plus 2 standard
deviations, but no larger than the font's max width */
fw = ((sum / n) + (((int) dev) << 1));
D_FONT(("Proportional font optimizations: Average width %d, standard deviation %3.2f, new width %d\n", (sum / n), dev, fw));
UPPER_BOUND(fw, max_w);
} else {
LOWER_BOUND(fw, TermWin.font->max_bounds.width);
}
} else {
LOWER_BOUND(fw, TermWin.font->max_bounds.width);
}
/* 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 */
return;
TermWin.fwidth = fw;
TermWin.fheight = fh;
@ -488,3 +516,138 @@ change_font(int init, const char *fontname)
}
return;
}
static unsigned char
get_corner(const char *corner)
{
if (!BEG_STRCASECMP(corner, "tl ") || !BEG_STRCASECMP(corner, "top_left")) {
return SHADOW_TOP_LEFT;
} else if (!BEG_STRCASECMP(corner, "tr ") || !BEG_STRCASECMP(corner, "top_right")) {
return SHADOW_TOP_RIGHT;
} else if (!BEG_STRCASECMP(corner, "bl ") || !BEG_STRCASECMP(corner, "bottom_left")) {
return SHADOW_BOTTOM_LEFT;
} else if (!BEG_STRCASECMP(corner, "br ") || !BEG_STRCASECMP(corner, "bottom_right")) {
return SHADOW_BOTTOM_RIGHT;
} else {
return 255;
}
}
void
set_shadow_color_by_name(unsigned char which, const char *color_name)
{
Pixel p;
ASSERT(which <= 4);
p = get_color_by_name(color_name, "#000000");
fshadow.color[which] = p;
fshadow.shadow[which] = fshadow.do_shadow = 1;
}
void
set_shadow_color_by_pixel(unsigned char which, Pixel p)
{
ASSERT(which <= 4);
fshadow.color[which] = p;
fshadow.shadow[which] = fshadow.do_shadow = 1;
}
/* Possible syntax for the font effects line:
font fx <topleft_color> <topright_color> <bottomleft_color> <bottomright_color>
font fx outline <color>
font fx shadow <color>
font fx emboss <dark_color> <light_color>
font fx carved <dark_color> <light_color>
^^^^^^^
|
\- This part is not included in the contents of the line variable.
*/
unsigned char
parse_font_fx(const char *line)
{
char *color, *corner;
unsigned char which, n;
Pixel p;
ASSERT(line != NULL);
n = NumWords(line);
if (!BEG_STRCASECMP(line, "none")) {
MEMSET(&fshadow, 0, sizeof(fontshadow_t));
} else if (!BEG_STRCASECMP(line, "outline")) {
if (n != 2) {
return 0;
}
color = Word(2, line);
p = get_color_by_name(color, "black");
FREE(color);
for (which = 0; which < 4; which++) {
set_shadow_color_by_pixel(which, p);
}
} else if (!BEG_STRCASECMP(line, "shadow")) {
if (n == 2) {
which = SHADOW_BOTTOM_RIGHT;
color = Word(2, line);
} else if (n == 3) {
color = Word(3, line);
corner = PWord(2, line);
which = get_corner(corner);
if (which >= 4) {
return 0;
}
} else {
return 0;
}
set_shadow_color_by_name(which, color);
FREE(color);
} else if (!BEG_STRCASECMP(line, "emboss")) {
if (n != 3) {
return 0;
}
color = Word(2, line);
p = get_color_by_name(color, "black");
set_shadow_color_by_pixel(SHADOW_BOTTOM_RIGHT, p);
FREE(color);
color = Word(3, line);
p = get_color_by_name(color, "white");
set_shadow_color_by_pixel(SHADOW_TOP_LEFT, p);
FREE(color);
} else if (!BEG_STRCASECMP(line, "carved")) {
if (n != 3) {
return 0;
}
color = Word(2, line);
p = get_color_by_name(color, "black");
set_shadow_color_by_pixel(SHADOW_TOP_LEFT, p);
FREE(color);
color = Word(3, line);
p = get_color_by_name(color, "white");
set_shadow_color_by_pixel(SHADOW_BOTTOM_RIGHT, p);
FREE(color);
} else {
unsigned char i;
for (i = 0; i < 4; i++) {
which = get_corner(line);
if (which >= 4) {
which = i;
color = Word(1, line);
line = PWord(2, line);
} else {
color = Word(2, line);
line = PWord(3, line);
}
set_shadow_color_by_name(which, color);
FREE(color);
if (line == NULL) {
break;
}
}
}
return 1;
}

View File

@ -40,6 +40,12 @@
#define BIGGER_FONT "#+"
#define SMALLER_FONT "#-"
/* These are subscripts for the arrays in a fontshadow_t */
#define SHADOW_TOP_LEFT 0
#define SHADOW_TOP_RIGHT 1
#define SHADOW_BOTTOM_LEFT 2
#define SHADOW_BOTTOM_RIGHT 3
#define NEXT_FONT(i) do { if (font_idx + ((i)?(i):1) >= font_cnt) {font_idx = font_cnt - 1;} else {font_idx += ((i)?(i):1);} \
while (!etfonts[font_idx]) {if (font_idx == font_cnt) {font_idx--; break;} font_idx++;} } while (0)
#define PREV_FONT(i) do { if (font_idx - ((i)?(i):1) < 0) {font_idx = 0;} else {font_idx -= ((i)?(i):1);} \
@ -58,11 +64,18 @@ typedef struct cachefont_struct {
struct cachefont_struct *next;
} cachefont_t;
typedef struct fontshadow_struct {
Pixel color[4];
unsigned char shadow[4];
unsigned char do_shadow;
} fontshadow_t;
/************ Variables ************/
extern unsigned char font_idx, def_font_idx, font_cnt, font_chg;
extern const char *def_fontName[];
extern char *rs_font[NFONTS];
extern char **etfonts, **etmfonts;
extern fontshadow_t fshadow;
# ifdef MULTI_CHARSET
extern const char *def_mfontName[];
extern char *rs_mfont[NFONTS];
@ -76,6 +89,9 @@ extern void eterm_font_delete(char **flist, unsigned char idx);
extern void *load_font(const char *, const char *, unsigned char);
extern void free_font(const void *);
extern void change_font(int, const char *);
extern void set_shadow_color_by_name(unsigned char, const char *);
extern void set_shadow_color_by_pixel(unsigned char, Pixel);
extern unsigned char parse_font_fx(const char *line);
_XFUNCPROTOEND

View File

@ -25,7 +25,6 @@
# define _MENUS_H
# include <X11/Xfuncproto.h>
# include <Imlib2.h>
# include "events.h"
# include "pixmap.h"

View File

@ -94,6 +94,7 @@ static char *rs_pipe_name = NULL;
static int rs_shade = 0;
static char *rs_tint = NULL;
static unsigned long rs_buttonbars = 1;
static char *rs_font_effects = NULL;
#if defined (HOTKEY_CTRL) || defined (HOTKEY_META)
static char *rs_bigfont_key = NULL;
static char *rs_smallfont_key = NULL;
@ -253,6 +254,7 @@ static const struct {
OPT_LONG("font2", "font 2", &rs_font[2]),
OPT_LONG("font3", "font 3", &rs_font[3]),
OPT_LONG("font4", "font 4", &rs_font[4]),
OPT_LONG("font-fx", "specify font effects for the terminal fonts", &rs_font_effects),
/* =======[ Pixmap options ]======= */
#ifdef PIXMAP_SUPPORT
@ -2020,6 +2022,11 @@ parse_attributes(char *buff, void *state)
} else if (!BEG_STRCASECMP(tmp, "default ")) {
def_font_idx = strtoul(PWord(2, tmp), (char **) NULL, 0);
} else if (!BEG_STRCASECMP(tmp, "fx ") || !BEG_STRCASECMP(tmp, "effect")) {
if (parse_font_fx(PWord(2, tmp)) != 1) {
print_error("Parse error in file %s, line %lu: Syntax error in font effects specification",
file_peek_path(), file_peek_line());
}
} else {
tmp = Word(1, tmp);
print_error("Parse error in file %s, line %lu: Invalid font index \"%s\"",
@ -3687,6 +3694,12 @@ post_parse(void)
}
#endif
}
if (rs_font_effects) {
if (parse_font_fx(rs_font_effects) != 1) {
print_error("Syntax error in the font effects specified on the command line.");
}
RESET_AND_ASSIGN(rs_font_effects, NULL);
}
/* Clean up image stuff */
for (i = 0; i < image_max; i++) {
@ -3713,6 +3726,9 @@ post_parse(void)
load_image(rs_pixmaps[i], images[i].norm);
FREE(rs_pixmaps[i]); /* These are created by StrDup() */
}
#else
/* Right now, solid mode is the only thing we can do without pixmap support. */
images[i].mode = MODE_SOLID & ALLOW_SOLID;
#endif
if (images[i].selected) {
/* If we have a bevel but no border, use the bevel as a border. */
@ -3965,6 +3981,12 @@ post_parse(void)
}
#endif
#ifdef MULTI_CHARSET
if (rs_multichar_encoding != NULL) {
set_multichar_encoding(rs_multichar_encoding);
}
#endif
if (rs_pipe_name) {
struct stat fst;

View File

@ -25,7 +25,9 @@
# define _PIXMAP_H
#include <X11/Xatom.h>
#include <Imlib2.h>
#ifdef PIXMAP_SUPPORT
# include <Imlib2.h>
#endif
#include "misc.h"

View File

@ -36,6 +36,7 @@ static const char cvs_ident[] = "$Id$";
#include "buttons.h"
#include "command.h"
#include "debug.h"
#include "font.h"
#include "startup.h"
#include "screen.h"
#include "scrollbar.h"
@ -94,8 +95,8 @@ unsigned char refresh_all = 0;
#ifdef MULTI_CHARSET
static short multi_byte = 0;
static enum {
EUCJ, EUCKR = EUCJ, GB = EUCJ, SJIS, BIG5
} encoding_method = EUCJ;
EUCJ, EUCKR = EUCJ, GB = EUCJ, SJIS, BIG5, LATIN1
} encoding_method = LATIN1;
static enum {
SBYTE, WBYTE
} chstat = SBYTE;
@ -738,51 +739,56 @@ scr_add_lines(const unsigned char *str, int nlines, int len)
for (i = 0; i < len;) {
c = str[i++];
#ifdef MULTI_CHARSET
if (chstat == WBYTE) {
if ((encoding_method != LATIN1) && (chstat == WBYTE)) {
rstyle |= RS_multiMask; /* multibyte 2nd byte */
chstat = SBYTE;
if (encoding_method == EUCJ)
if (encoding_method == EUCJ) {
c |= 0x80; /* maybe overkill, but makes it selectable */
} else if (chstat == SBYTE)
if (multi_byte || (c & 0x80)) { /* multibyte 1st byte */
}
} else if (chstat == SBYTE) {
if ((encoding_method != LATIN1) && (multi_byte || (c & 0x80))) { /* multibyte 1st byte */
rstyle &= ~RS_multiMask;
rstyle |= RS_multi1;
chstat = WBYTE;
if (encoding_method == EUCJ)
if (encoding_method == EUCJ) {
c |= 0x80; /* maybe overkill, but makes it selectable */
}
} else
#endif
switch (c) {
case 127:
continue; /* ummmm..... */
case '\t':
scr_tab(1);
continue;
case '\n':
MAX_IT(stp[last_col], screen.col);
screen.flags &= ~Screen_WrapNext;
if (screen.row == screen.bscroll) {
scroll_text(screen.tscroll, screen.bscroll, 1, 0);
j = screen.bscroll + TermWin.saveLines;
switch (c) {
case 127:
continue; /* ummmm..... */
case '\t':
scr_tab(1);
continue;
case '\n':
MAX_IT(stp[last_col], screen.col);
screen.flags &= ~Screen_WrapNext;
if (screen.row == screen.bscroll) {
scroll_text(screen.tscroll, screen.bscroll, 1, 0);
j = screen.bscroll + TermWin.saveLines;
blank_screen_mem(screen.text, screen.rend, j, DEFAULT_RSTYLE | ((rstyle & RS_RVid) ? (RS_RVid) : (0)));
} else if (screen.row < (TermWin.nrow - 1)) {
screen.row++;
row = screen.row + TermWin.saveLines;
}
stp = screen.text[row]; /* _must_ refresh */
srp = screen.rend[row]; /* _must_ refresh */
continue;
case '\r':
MAX_IT(stp[last_col], screen.col);
screen.flags &= ~Screen_WrapNext;
screen.col = 0;
continue;
default:
} else if (screen.row < (TermWin.nrow - 1)) {
screen.row++;
row = screen.row + TermWin.saveLines;
}
stp = screen.text[row]; /* _must_ refresh */
srp = screen.rend[row]; /* _must_ refresh */
continue;
case '\r':
MAX_IT(stp[last_col], screen.col);
screen.flags &= ~Screen_WrapNext;
screen.col = 0;
continue;
default:
#ifdef MULTI_CHARSET
rstyle &= ~RS_multiMask;
rstyle &= ~RS_multiMask;
#endif
break;
}
#ifdef MULTI_CHARSET
}
#endif
break;
}
if (screen.flags & Screen_WrapNext) {
stp[last_col] = WRAP_CHAR;
if (screen.row == screen.bscroll) {
@ -1381,11 +1387,20 @@ scr_charset_set(int set, unsigned int ch)
#ifdef MULTI_CHARSET
static void latin1(unsigned char *str, int len);
static void eucj2jis(unsigned char *str, int len);
static void sjis2jis(unsigned char *str, int len);
static void big5dummy(unsigned char *str, int len);
static void (*multichar_decode) (unsigned char *str, int len) = eucj2jis;
static void (*multichar_decode) (unsigned char *str, int len) = latin1;
static void
latin1(unsigned char *str, int len)
{
return;
str = NULL;
len = 0;
}
static void
eucj2jis(unsigned char *str, int len)
@ -1431,16 +1446,18 @@ set_multichar_encoding(const char *str)
{
#ifdef MULTI_CHARSET
if (str && *str) {
if (!strcmp(str, "sjis")) {
if (!strcasecmp(str, "sjis")) {
encoding_method = SJIS;
multichar_decode = sjis2jis;
} else if (!strcmp(str, "eucj") || !strcmp(str, "euckr")
|| !strcmp(str, "gb")) {
} else if (!strcasecmp(str, "eucj") || !strcasecmp(str, "euckr") || !strcasecmp(str, "gb")) {
encoding_method = EUCJ;
multichar_decode = eucj2jis;
} else if (!strcmp(str, "big5")) {
} else if (!strcasecmp(str, "big5")) {
encoding_method = BIG5;
multichar_decode = big5dummy;
} else {
encoding_method = LATIN1;
multichar_decode = latin1;
}
}
#else
@ -1734,7 +1751,7 @@ scr_refresh(int type)
drp[col] = srp[col];
buffer[len++] = stp[col];
col++;
if ((col == ncols) || (srp[col] != rend))
if ((col == ncols) || (srp[col] != (unsigned int) rend))
break;
if ((stp[col] == dtp[col])
&& (srp[col] == drp[col])
@ -1779,7 +1796,7 @@ scr_refresh(int type)
dtp[col] = stp[col];
drp[col] = srp[col];
buffer[len++] = stp[col];
} /* for (; ++col < TermWin.ncol - 1;) */
}
col--;
wlen = len;
#ifdef MULTI_CHARSET
@ -1908,44 +1925,101 @@ scr_refresh(int type)
UPDATE_BOX(xpixel + 1, ypixel - TermWin.font->ascent, xpixel + 1 + Width2Pixel(1), ypixel + Height2Pixel(1));
}
#endif
} else
} else {
#ifdef PIXMAP_SUPPORT
if (background_is_pixmap() && (back == bgColor)) {
CLEAR_CHARS(xpixel, ypixel - TermWin.font->ascent, len);
DRAW_STRING(draw_string, xpixel, ypixel, buffer, wlen);
UPDATE_BOX(xpixel, ypixel - TermWin.font->ascent, xpixel + Width2Pixel(len), ypixel + Height2Pixel(1));
} else
if (background_is_pixmap() && (back == bgColor)) {
if (fshadow.do_shadow) {
Pixel tmp;
int xx, yy, ww, hh;
tmp = gcvalue.foreground;
xx = xpixel;
yy = ypixel - TermWin.font->ascent;
ww = Width2Pixel(wlen);
hh = Height2Pixel(1);
CLEAR_CHARS(xpixel, ypixel - TermWin.font->ascent, wlen);
if (fshadow.shadow[SHADOW_TOP_LEFT] || fshadow.shadow[SHADOW_TOP_RIGHT]) {
yy--;
hh++;
}
if (fshadow.shadow[SHADOW_BOTTOM_LEFT] || fshadow.shadow[SHADOW_BOTTOM_RIGHT]) {
hh++;
if (row < nrows - 1) {
int ii;
for (ii = col - len + 1; ii <= col; ii++) {
drawn_text[row + 1][ii] = 0;
}
}
}
if (fshadow.shadow[SHADOW_TOP_LEFT]) {
XSetForeground(Xdisplay, TermWin.gc, fshadow.color[SHADOW_TOP_LEFT]);
DRAW_STRING(draw_string, xpixel - 1, ypixel - 1, buffer, wlen);
if (col) {
dtp[col - 1] = 0;
}
}
if (fshadow.shadow[SHADOW_TOP_RIGHT]) {
XSetForeground(Xdisplay, TermWin.gc, fshadow.color[SHADOW_TOP_RIGHT]);
DRAW_STRING(draw_string, xpixel + 1, ypixel - 1, buffer, wlen);
if (col < ncols - 1) {
dtp[col + 1] = 0;
}
}
if (fshadow.shadow[SHADOW_BOTTOM_LEFT]) {
XSetForeground(Xdisplay, TermWin.gc, fshadow.color[SHADOW_BOTTOM_LEFT]);
DRAW_STRING(draw_string, xpixel - 1, ypixel + 1, buffer, wlen);
if (col) {
dtp[col - 1] = 0;
}
}
if (fshadow.shadow[SHADOW_BOTTOM_RIGHT]) {
XSetForeground(Xdisplay, TermWin.gc, fshadow.color[SHADOW_BOTTOM_RIGHT]);
DRAW_STRING(draw_string, xpixel + 1, ypixel + 1, buffer, wlen);
if (col < ncols - 1) {
dtp[col + 1] = 0;
}
}
XSetForeground(Xdisplay, TermWin.gc, tmp);
DRAW_STRING(draw_string, xpixel, ypixel, buffer, wlen);
UPDATE_BOX(xx, yy, xx + ww, yy + hh);
} else {
CLEAR_CHARS(xpixel, ypixel - TermWin.font->ascent, wlen);
DRAW_STRING(draw_string, xpixel, ypixel, buffer, wlen);
UPDATE_BOX(xpixel, ypixel - TermWin.font->ascent, xpixel + Width2Pixel(wlen), ypixel + Height2Pixel(1));
}
} else
#endif
{
{
#ifdef FORCE_CLEAR_CHARS
CLEAR_CHARS(xpixel, ypixel - TermWin.font->ascent, len);
CLEAR_CHARS(xpixel, ypixel - TermWin.font->ascent, wlen);
#endif
DRAW_STRING(draw_image_string, xpixel, ypixel, buffer, wlen);
UPDATE_BOX(xpixel, ypixel - TermWin.font->ascent, xpixel + Width2Pixel(len), ypixel + Height2Pixel(1));
DRAW_STRING(draw_image_string, xpixel, ypixel, buffer, wlen);
UPDATE_BOX(xpixel, ypixel - TermWin.font->ascent, xpixel + Width2Pixel(wlen), ypixel + Height2Pixel(1));
}
}
/* do the convoluted bold overstrike */
#ifndef NO_BOLDOVERSTRIKE
if (MONO_BOLD(rend)) {
DRAW_STRING(draw_string, xpixel + 1, ypixel, buffer, wlen);
UPDATE_BOX(xpixel + 1, ypixel - TermWin.font->ascent, xpixel + 1 + Width2Pixel(len), ypixel + Height2Pixel(1));
UPDATE_BOX(xpixel + 1, ypixel - TermWin.font->ascent, xpixel + 1 + Width2Pixel(wlen), ypixel + Height2Pixel(1));
}
#endif
if ((rend & RS_Uline) && (TermWin.font->descent > 1)) {
XDrawLine(Xdisplay, draw_buffer, TermWin.gc, xpixel, ypixel + 1, xpixel + Width2Pixel(len) - 1, ypixel + 1);
UPDATE_BOX(xpixel, ypixel + 1, xpixel + Width2Pixel(len) - 1, ypixel + 1);
XDrawLine(Xdisplay, draw_buffer, TermWin.gc, xpixel, ypixel + 1, xpixel + Width2Pixel(wlen) - 1, ypixel + 1);
UPDATE_BOX(xpixel, ypixel + 1, xpixel + Width2Pixel(wlen) - 1, ypixel + 1);
}
if (is_cursor == 1) {
#ifndef NO_CURSORCOLOR
if (PixColors[cursorColor] != PixColors[bgColor]) {
gcvalue.foreground = PixColors[cursorColor];
gcmask |= GCForeground;
XChangeGC(Xdisplay, TermWin.gc, gcmask, &gcvalue);
XSetForeground(Xdisplay, TermWin.gc, PixColors[cursorColor]);
}
#endif
XDrawRectangle(Xdisplay, draw_buffer, TermWin.gc, xpixel, ypixel - TermWin.font->ascent, Width2Pixel(1 + wbyte) - 1, Height2Pixel(1) - 1);
UPDATE_BOX(xpixel, ypixel - TermWin.font->ascent, Width2Pixel(1 + wbyte) - 1, Height2Pixel(1) - 1);
XSetForeground(Xdisplay, TermWin.gc, PixColors[fgColor]);
}
if (gcmask) { /* restore normal colors */
gcvalue.foreground = PixColors[fgColor];
@ -1975,10 +2049,41 @@ scr_refresh(int type)
#endif
}
if (buffer_pixmap) {
D_SCREEN(("Update box dimensions: from (%d, %d) to (%d, %d). Dimensions %dx%d\n", low_x, low_y, high_x, high_y,
high_x - low_x + 1, high_y - low_y + 1));
XClearArea(Xdisplay, TermWin.vt, low_x, low_y, high_x - low_x + 1, high_y - low_y + 1, False);
if (fshadow.shadow[SHADOW_TOP_LEFT] || fshadow.shadow[SHADOW_BOTTOM_LEFT]) {
XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, TermWin.internalBorder - 1, 0,
1, TermWin_TotalHeight() - 1, TermWin.internalBorder - 1, 0);
XClearArea(Xdisplay, TermWin.vt, TermWin.internalBorder - 1, 0, 1, TermWin_TotalHeight() - 1, False);
}
if (fshadow.shadow[SHADOW_TOP_RIGHT] || fshadow.shadow[SHADOW_BOTTOM_RIGHT] || boldlast) {
XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, TermWin_TotalWidth() - 2, 0,
1, TermWin_TotalHeight() - 1, TermWin_TotalWidth() - 2, 0);
XClearArea(Xdisplay, TermWin.vt, TermWin_TotalWidth() - 2, 0, 1, TermWin_TotalHeight() - 1, False);
}
if (fshadow.shadow[SHADOW_TOP_LEFT] || fshadow.shadow[SHADOW_TOP_RIGHT]) {
XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, 0, TermWin.internalBorder - 1,
TermWin_TotalWidth() - 1, 1, 0, TermWin.internalBorder - 1);
XClearArea(Xdisplay, TermWin.vt, 0, TermWin.internalBorder - 1, TermWin_TotalWidth() - 1, 1, False);
}
if (fshadow.shadow[SHADOW_BOTTOM_LEFT] || fshadow.shadow[SHADOW_BOTTOM_RIGHT]) {
XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, 0, TermWin_TotalHeight() - TermWin.internalBorder,
TermWin_TotalWidth() - 1, 1, 0, TermWin_TotalHeight() - TermWin.internalBorder);
XClearArea(Xdisplay, TermWin.vt, 0, TermWin_TotalHeight() - TermWin.internalBorder, TermWin_TotalWidth() - 1, 1, False);
}
} else {
if (boldlast) {
XClearArea(Xdisplay, TermWin.vt, TermWin_TotalWidth() - 2, 0, 1, TermWin_TotalHeight() - 1, 0);
if (fshadow.shadow[SHADOW_TOP_LEFT] || fshadow.shadow[SHADOW_BOTTOM_LEFT]) {
XClearArea(Xdisplay, TermWin.vt, TermWin.internalBorder - 1, 0, 1, TermWin_TotalHeight() - 1, False);
}
if ((fshadow.shadow[SHADOW_TOP_RIGHT] || fshadow.shadow[SHADOW_BOTTOM_RIGHT] || boldlast) && TermWin.internalBorder) {
XClearArea(Xdisplay, TermWin.vt, TermWin_TotalWidth() - 2, 0, 1, TermWin_TotalHeight() - 1, False);
}
if (fshadow.shadow[SHADOW_TOP_LEFT] || fshadow.shadow[SHADOW_TOP_RIGHT]) {
XClearArea(Xdisplay, TermWin.vt, 0, TermWin.internalBorder - 1, TermWin_TotalWidth() - 1, 1, False);
}
if (fshadow.shadow[SHADOW_BOTTOM_LEFT] || fshadow.shadow[SHADOW_BOTTOM_RIGHT]) {
XClearArea(Xdisplay, TermWin.vt, 0, TermWin_TotalHeight() - TermWin.internalBorder, TermWin_TotalWidth() - 1, 1, False);
}
}
if (type == SLOW_REFRESH) {

View File

@ -51,6 +51,9 @@
#define CLEAR_CHARS(x, y, num) ((buffer_pixmap) \
? (XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, x, y, Width2Pixel(num), Height2Pixel(1), x, y)) \
: (XClearArea(Xdisplay, TermWin.vt, x, y, Width2Pixel(num), Height2Pixel(1), 0)))
#define CLEAR_RECT(x, y, w, h) ((buffer_pixmap) \
? (XCopyArea(Xdisplay, pmap, buffer_pixmap, TermWin.gc, x, y, w, h, x, y)) \
: (XClearArea(Xdisplay, TermWin.vt, x, y, w, h, 0)))
#define UPDATE_BOX(x1, y1, x2, y2) do {if (buffer_pixmap) {if (x1 < low_x) low_x = x1; if (x2 > high_x) high_x = x2; \
if (y1 < low_y) low_y = y1; if (y2 > high_y) high_y = y2;}} while (0)
#define ERASE_ROWS(row, num) do {XFillRectangle(Xdisplay, draw_buffer, TermWin.gc, Col2Pixel(0), Row2Pixel(row), TermWin.width, Height2Pixel(num)); \

View File

@ -26,8 +26,8 @@
#include <X11/Xfuncproto.h>
#include <ctype.h>
#include <Imlib2.h>
#include "events.h"
#include "pixmap.h"
/************ Macros and Definitions ************/
/* Scrollbar types we support */