Index: kit/configure
diff -u kit/configure:1.55 kit/configure:1.57
--- kit/configure:1.55	Fri Apr 23 17:14:24 1999
+++ kit/configure	Sun May 16 01:15:56 1999
@@ -1019,12 +1019,12 @@
 if test "$mgp_use_freetype" = "yes"; then
  	echo $ac_n "checking for freetype library/header""... $ac_c" 1>&6
 echo "configure:1022: checking for freetype library/header" >&5
- 	for dir in /usr/local/freetype /usr/local /opt/freetype /usr; do
+ 	for dir in /usr/local/freetype /usr/local /opt/freetype /usr/pkg /usr; do
  		ac_cv_ft_lib=no
  		ac_cv_ft_include=no
- 		if test -d $dir/lib -a -f $dir/lib/libttf.so; then
+ 		if test -d $dir/lib -a -f "$dir/lib/libttf.so*"; then
  			ac_cv_ft_lib="$dir/lib"
- 			ac_cv_ft_libpath="libttf.so"
+ 			ac_cv_ft_libpath=`ls $dir/lib/libttf.so* | head -1 | sed -e 's/.*\///'`
  		elif test -d $dir/lib -a -f $dir/lib/libttf.a; then
  			ac_cv_ft_lib="$dir/lib"
  			ac_cv_ft_libpath="libttf.a"
@@ -1161,7 +1161,7 @@
 if test "$mgp_use_vflib" = "yes"; then
 	echo $ac_n "checking for VFlib library/header""... $ac_c" 1>&6
 echo "configure:1164: checking for VFlib library/header" >&5
-	for dir in /usr/local/VFlib /usr/local/vflib /usr/local; do
+	for dir in /usr/local/VFlib /usr/local/vflib /usr/local /usr/pkg; do
 		ac_cv_vf_libname=VFlib
 		ac_cv_vf_libdir=no
 		ac_cv_vf_hdrdir=no
Index: kit/configure.in
diff -u kit/configure.in:1.52 kit/configure.in:1.54
--- kit/configure.in:1.52	Fri Apr 23 17:14:25 1999
+++ kit/configure.in	Sun May 16 01:15:58 1999
@@ -3,7 +3,7 @@
 dnl independent (using srcdir), however, xmkmf and Imake.tmpl do not
 dnl allow us to switch compilation directory.
 dnl
-dnl $Id: configure.in,v 1.52 1999/04/23 08:14:25 itojun Exp $
+dnl $Id: configure.in,v 1.54 1999/05/15 16:15:58 nishida Exp $
 AC_INIT(image/imagetypes.c)
 
 dnl Checks for programs.
@@ -65,12 +65,12 @@
  
 if test "$mgp_use_freetype" = "yes"; then
  	AC_MSG_CHECKING(for freetype library/header)
- 	for dir in /usr/local/freetype /usr/local /opt/freetype /usr; do
+ 	for dir in /usr/local/freetype /usr/local /opt/freetype /usr/pkg /usr; do
  		ac_cv_ft_lib=no
  		ac_cv_ft_include=no
- 		if test -d $dir/lib -a -f $dir/lib/libttf.so; then
+ 		if test -d $dir/lib -a -f "$dir/lib/libttf.so*"; then
  			ac_cv_ft_lib="$dir/lib"
- 			ac_cv_ft_libpath="libttf.so"
+ 			ac_cv_ft_libpath=`ls $dir/lib/libttf.so* | head -1 | sed -e 's/.*\///'`
  		elif test -d $dir/lib -a -f $dir/lib/libttf.a; then
  			ac_cv_ft_lib="$dir/lib"
  			ac_cv_ft_libpath="libttf.a"
@@ -119,7 +119,7 @@
 
 if test "$mgp_use_vflib" = "yes"; then
 	AC_MSG_CHECKING(for VFlib library/header)
-	for dir in /usr/local/VFlib /usr/local/vflib /usr/local; do
+	for dir in /usr/local/VFlib /usr/local/vflib /usr/local /usr/pkg; do
 		ac_cv_vf_libname=VFlib
 		ac_cv_vf_libdir=no
 		ac_cv_vf_hdrdir=no
Index: kit/ctlwords.pl
diff -u kit/ctlwords.pl:1.2 kit/ctlwords.pl:removed
--- kit/ctlwords.pl:1.2	Sat Sep  5 06:05:08 1998
+++ kit/ctlwords.pl	Mon May 17 05:10:06 1999
@@ -1,12 +0,0 @@
-#! /usr/bin/perl
-$counter = 0;	# 0 origin
-print "/* generated by ctlwords.awk. do not edit by hand. */\n";
-
-while (<>) {
-	next if (!/^\/\*CTL\*\//);
-	next if ($_ !~ /(CTL_[A-Z0-9]+)/);
-
-	$word = $1;
-	print "#define $word\t$counter\n";
-	$counter++;
-}
Index: kit/draw.c
diff -u kit/draw.c:1.143 kit/draw.c:1.146
--- kit/draw.c:1.143	Sat Apr 24 11:43:00 1999
+++ kit/draw.c	Sun May 16 02:55:38 1999
@@ -26,16 +26,17 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: draw.c,v 1.143 1999/04/24 02:43:00 itojun Exp $
+ * $Id: draw.c,v 1.146 1999/05/15 17:55:38 nishida Exp $
  */
 
 #include "mgp.h"
 
 /* state associated with the window - how should we treat this? */
-static struct ctrl *bg_image_ctl = NULL;
-static struct ctrl *bg_image_prev = NULL;
-static Image *bg_image = NULL;
-static XImageInfo *bg_ximageinfo = NULL;
+static struct ctrl *bg_image_ctl[2] = {NULL, NULL};
+static struct ctrl *bg_image_prev[2] = {NULL, NULL};
+static Image *bg_image[2] = {NULL, NULL};
+static XImageInfo *bg_ximageinfo[2] = {NULL, NULL};
+struct render_state cache_state;
 
 static u_short kinsokutable[] = {
 	0x2121, 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128,
@@ -46,9 +47,9 @@
 };
 
 #define	COMPLEX_BGIMAGE \
-    (bg_image_prev				\
-     && ((bg_image_prev->ct_op == CTL_BIMAGE)	\
-       || bg_image_prev->ct_op == CTL_BGRAD))
+    (bg_image_prev[caching]				\
+     && ((bg_image_prev[caching]->ct_op == CTL_BIMAGE)	\
+       || bg_image_prev[caching]->ct_op == CTL_BGRAD))
 
 #define	POSY(size)	(-(int)((size)/2))
 
@@ -107,6 +108,17 @@
 static void x_registerseed __P((struct render_state *, char *, char *));
 static char *x_findseed __P((struct render_state *, char *));
 
+static void XClearPixmap __P((Display *, Drawable));
+static void XSetPixmapBackgroundPixmap __P((Display *, Drawable, Pixmap, 
+	int, int));
+static void XSetPixmapBackground __P((Display *, Drawable, u_long));
+static void cache_page __P((struct render_state *, int));
+static void cache_effect1 __P((void));
+static void cache_effect2 __P((void));
+static void set_from_cache __P((struct render_state *));
+
+#define CHECK_CACHE {if (caching){caching = -1; return;}}
+
 static int
 ispsfilename(p0)
 	char *p0;
@@ -181,11 +193,19 @@
 	if (page_attribute[state->page].pg_linenum < state->line) {
 		if (state->page < maxpage) {
 			purgechild(state->page);
-			state->phase = P_NONE;
-			state->page++;
-			state->line = 0;
-			state_newpage(state);
-			state_init(state);
+
+			if (mgp_flag & FL_FRDCACHE &&
+				cached_page == state->page + 1){
+					/* Hit cache */
+					set_from_cache(state);
+					cache_hit = 1;
+			} else {
+				state->phase = P_NONE;
+				state->page++;
+				state->line = 0;
+				state_newpage(state);
+				state_init(state);
+			}
 		} else
 			state->phase = P_END;
 	}
@@ -250,6 +270,11 @@
 			pause = 0;
 			if (state->cp)
 				process_direc(state, &pause);
+			if (caching == -1){
+				/* caching failed */
+				caching = 0;
+				return;
+			}
 			if (lastcp && state->cp == lastcp)
 				goto done;
 			if (pause) {
@@ -368,15 +393,26 @@
 		if (ttykey_enable)
 			FD_SET(0, &fds);
 #endif
+
+		/* always cache next page */
+		if ((mgp_flag & FL_FRDCACHE) && cache_mode)
+			cache_page(&cache_state, state->page +1);
+
 		/* wait for something */
 		tout.tv_sec = 2;
 		tout.tv_usec = 0;
 		(void)select(xfd + 1, &fds, NULL, NULL, &tout);
-		timebar(state);
+
 #ifdef TTY_KEYINPUT
 		if (!(mgp_flag & FL_NOSTDIN) && !ttykey_enable)
 			try_enable_ttykey();
 #endif
+		/* we have no event in 2sec, so..*/
+		if (!FD_ISSET(xfd, &fds)){
+			if ((mgp_flag & FL_FRDCACHE) && !cache_mode)
+				cache_page(&cache_state, state->page +1);
+			timebar(state);
+		}
 	}
 	/*NOTREACHED*/
 }
@@ -397,53 +433,56 @@
 		debug0(cp);
 	}
 
+
 	switch(cp->ct_op) {
 	case CTL_SIZE:
-		char_size = state->height * cp->ctf_value / 100;
+		char_size[caching] = state->height * cp->ctf_value / 100;
 #ifdef FREETYPE
-		tfc_setsize(char_size);
+		tfc_setsize(char_size[caching]);
 #endif
 		break;
 
 	case CTL_VGAP:
-		vert_gap = cp->cti_value;
+		vert_gap[caching] = cp->cti_value;
 		break;
 
 	case CTL_HGAP:
-		horiz_gap = cp->cti_value;
+		horiz_gap[caching] = cp->cti_value;
 		break;
 
 	case CTL_GAP:
-		vert_gap = horiz_gap = cp->cti_value;
+		vert_gap[caching] = horiz_gap[caching] = cp->cti_value;
 		break;
 
 	case CTL_QUALITY:
 		if (!quality_flag)
-			b_quality = cp->cti_value;
+			b_quality[caching] = cp->cti_value;
 		break;
 
 	case CTL_PAUSE:
+		CHECK_CACHE
 		if (seenpause)
 			*seenpause = 1;
 		break;
 
 	case CTL_AGAIN:
+		CHECK_CACHE
 		if (state->have_mark)
 			state->ypos = state->mark_ypos;
 		state->have_mark = 0;
 		break;
 
 	case CTL_FORE:
-		fore_color = cp->ctl_value;
-		XSetForeground(display, gcfore, fore_color);
+		fore_color[caching] = cp->ctl_value;
+		XSetForeground(display, gcfore, fore_color[caching]);
 		break;
 
 	case CTL_BACK:
-		bg_image_ctl = cp;	/*update later*/
+		bg_image_ctl[caching] = cp;	/*update later*/
 		break;
 
 	case CTL_CCOLOR:
-		ctrl_color = cp->ctl_value;
+		ctrl_color[caching] = cp->ctl_value;
 		break;
 
 	case CTL_CENTER:
@@ -513,24 +552,27 @@
 	case CTL_BIMAGE:
 		if (mgp_flag & FL_BIMAGE)
 			break;
-		bg_image_ctl = cp;	/*update later*/
+		bg_image_ctl[caching] = cp;	/*update later*/
 		break;
 
 	case CTL_BGRAD:
 		if (mgp_flag & FL_BIMAGE)
 			break;
-		bg_image_ctl = cp;	/*update later*/
+		bg_image_ctl[caching] = cp;	/*update later*/
 		break;
 
 	case CTL_LCUTIN:
+		CHECK_CACHE
 		state->special = SP_LCUTIN;
 		break;
 
 	case CTL_RCUTIN:
+		CHECK_CACHE
 		state->special = SP_RCUTIN;
 		break;
 
 	case CTL_SHRINK:
+		CHECK_CACHE
 		state->special = SP_SHRINK;
 		break;
 
@@ -565,33 +607,44 @@
 
 	case CTL_LINESTART:
 		if (state->line == 0) {
-			if (bg_image_ctl) {
-				if (bg_image_prev
-				 && ctlcmp(bg_image_ctl, bg_image_prev) == 0) {
+			if (bg_image_ctl[caching]) {
+				if (bg_image_prev[caching]
+				 && ctlcmp(bg_image_ctl[caching], 
+					bg_image_prev[caching]) == 0) {
 					; /* same as the last time */
-				} else if (bg_image_ctl->ct_op == CTL_BIMAGE) {
-				    image_load(state, bg_image_ctl->ctm_fname,
-					bg_image_ctl->ctm_numcolor,
-					bg_image_ctl->ctm_ximagesize,
-					bg_image_ctl->ctm_yimagesize, 1,
-					bg_image_ctl->ctm_zoomflag, 0);
-				} else if (bg_image_ctl->ct_op == CTL_BGRAD) {
+				} else if (bg_image_ctl[caching]->ct_op == CTL_BIMAGE) {
+				    image_load(state, bg_image_ctl[caching]->ctm_fname,
+					bg_image_ctl[caching]->ctm_numcolor,
+					bg_image_ctl[caching]->ctm_ximagesize,
+					bg_image_ctl[caching]->ctm_yimagesize, 1,
+					bg_image_ctl[caching]->ctm_zoomflag, 0);
+				} else if (bg_image_ctl[caching]->ct_op == CTL_BGRAD) {
 					back_gradation(state,
-						&bg_image_ctl->ct_val.ctrl_grad);
-				} else if (bg_image_ctl->ct_op == CTL_BACK) {
-					XSetWindowBackground(display,
-						state->target,
-						bg_image_ctl->ctl_value);
-					back_color = bg_image_ctl->ctl_value;
+						&bg_image_ctl[caching]->ct_val.ctrl_grad);
+				} else if (bg_image_ctl[caching]->ct_op == CTL_BACK) {
+					if (!caching)
+						XSetWindowBackground(display,
+							state->target, bg_image_ctl[caching]->ctl_value);
+					else {
+						XSetPixmapBackground(display,
+							state->target, bg_image_ctl[caching]->ctl_value);
+					}
+					back_color[caching] = bg_image_ctl[caching]->ctl_value;
 				} else {
 					fprintf(stderr, "internal error: "
 						"bogus background\n");
 					cleanup(-1);
 				}
 			}
-			XClearWindow(display, state->target);
-			bg_image_prev = bg_image_ctl;
-			bg_image_ctl = NULL;
+
+			if (!caching) 
+				XClearWindow(display, state->target);
+			else 
+				XClearPixmap(display, state->target);
+
+			bg_image_prev[caching] = bg_image_ctl[caching];
+			bg_image_ctl[caching] = NULL;
+
 			if (t_fin)
 				timebar(state);
 		}
@@ -601,8 +654,8 @@
 	case CTL_LINEEND:
 		/* blank lines */
 		if (state->maxascent + state->maxdescent < 3) {	/*XXX*/
-			state->maxascent = char_size;
-			state->maxdescent = VERT_GAP(char_size);
+			state->maxascent = char_size[caching];
+			state->maxdescent = VERT_GAP(char_size[caching]);
 		}
 		draw_line_end(state);
 		/* reset single-line oriented state */
@@ -620,10 +673,12 @@
 		break;
 
 	case CTL_SYSTEM:
+		CHECK_CACHE
 		process_system(state, cp);
 		break;
 
 	case CTL_XSYSTEM:
+		CHECK_CACHE
 		process_xsystem(state, cp);
 		break;
 
@@ -801,7 +856,7 @@
 
 	cutinWin = XCreateSimpleWindow(display, state->target,
 		sx, ly, state->linewidth, state->maxascent + state->maxdescent,
-		0, fore_color, back_color);
+		0, fore_color[caching], back_color[caching]);
 	XSetWindowBackgroundPixmap(display, cutinWin, None);
 	XMapSubwindows(display, state->target);
 
@@ -995,20 +1050,20 @@
 
 #if 0
 		if (code == ' ') {
-			char_len = char_size / 2;
+			char_len = char_size[caching] / 2;
 			p++;
 			len--;
 
-			state->linewidth += HORIZ_STEP(char_size, char_len);
+			state->linewidth += HORIZ_STEP(char_size[caching], char_len);
 			continue;
 		}
 #endif
 		if (code == '\t') {
-			char_len = char_size / 2;
+			char_len = char_size[caching] / 2;
 			p++;
 			len--;
 
-			char_len = HORIZ_STEP(char_size, char_len) * 8;/*XXX*/
+			char_len = HORIZ_STEP(char_size[caching], char_len) * 8;/*XXX*/
 			state->linewidth = (state->linewidth + char_len) / char_len * char_len;
 			continue;
 		}
@@ -1034,7 +1089,7 @@
 #ifdef FREETYPE_CHARSET16
 			if (!(mgp_flag & FL_NOFREETYPE)
 			 && strncmp(registry, "jisx0208.1983-", 14) == 0) {
-				if (tfc_get(code, char_size, 1, registry,
+				if (tfc_get(code, char_size[caching], 1, registry,
 						charset16)){
 					mode = MODE_FREETYPE;
 				}
@@ -1045,7 +1100,7 @@
 		} else {
 #ifdef FREETYPE
 			if (!(mgp_flag & FL_NOFREETYPE)) {
-				if (tfc_get(code, char_size, 1, registry,
+				if (tfc_get(code, char_size[caching], 1, registry,
 						charset16)) {
 					mode = MODE_FREETYPE;
 				}
@@ -1060,7 +1115,7 @@
 				int ts;
 				xfontstruct = x_setfont(
 					x_findseed(state, registry),
-					char_size, registry, &ts);
+					char_size[caching], registry, &ts);
 				if (ts)
 					mode = MODE_X;
 			}
@@ -1086,9 +1141,9 @@
 		case MODE_VFLIB:
 			char_len = draw_onechar_vf(state, code,
 				state->linewidth, 0,
-				registry ? char_size
-					 : (char_size * 4 / 5), /*XXX*/
-				char_size);
+				registry ? char_size[caching]
+					 : (char_size[caching] * 4 / 5), /*XXX*/
+				char_size[caching]);
 			break;
 #endif
 #ifdef FREETYPE
@@ -1100,7 +1155,7 @@
 			 */
 			char_len = draw_onechar_tf(state, code,
 				state->linewidth, 0,
-				char_size, registry,
+				char_size[caching], registry,
 				(len == (charset16 ? 2 : 1)) ? 1 : 0,
 				charset16);
 			break;
@@ -1112,7 +1167,7 @@
 		case MODE_UNKNOWN:
 		case MODE_X:
 			char_len = draw_onechar_x(state, code,
-				state->linewidth, 0, char_size,
+				state->linewidth, 0, char_size[caching],
 				registry, (len == (charset16 ? 2 : 1)) ? 1 : 0);
 			if (char_len == 0) {
 				fprintf(stderr, "can't load font size %d "
@@ -1127,7 +1182,7 @@
 		p += (charset16 ? 2 : 1);
 		len -= (charset16 ? 2 : 1);
 
-		state->linewidth += HORIZ_STEP(char_size, char_len);
+		state->linewidth += HORIZ_STEP(char_size[caching], char_len);
 	}
 
 	if (state->width - state->leftfillpos / 2 < state->linewidth
@@ -1267,7 +1322,7 @@
 		return 0;
 	obj->x = x;
 	obj->y = y;
-	obj->fore = fore_color;
+	obj->fore = fore_color[caching];
 	obj->type = O_VFONT;
 	obj->data.vfc = vfc;
 	obj->data.vfc->size = size;
@@ -1293,7 +1348,7 @@
 		return 0;
 	obj->x = x;
 	obj->y = y;
-	obj->fore = fore_color;
+	obj->fore = fore_color[caching];
 	obj->type = O_TFONT;
 	obj->data.tfc = tfc;
 	obj->ascent = obj->data.tfc->ascent;
@@ -1319,7 +1374,7 @@
 		return 0;
 	obj->x = x;
 	obj->y = y;
-	obj->fore = fore_color;
+	obj->fore = fore_color[caching];
 	obj->type = O_XFONT;
 	obj->data.xfont.xfont = x_findseed(state, registry);
 	obj->data.xfont.csize = size;
@@ -1488,8 +1543,8 @@
 	int inithist;
 
 	if (!COMPLEX_BGIMAGE) {
-		if (back_color != xcol.pixel) {
-			xcol.pixel = back_color;
+		if (back_color[caching] != xcol.pixel) {
+			xcol.pixel = back_color[caching];
 			xcol.flags = DoRed|DoGreen|DoBlue;
 			XQueryColor(display, colormap, &xcol);
 		}
@@ -1516,8 +1571,8 @@
 		bw = bh = 0;	/* for lint */
 		goto end;
 	}
-	bw = bg_image->width;
-	bh = bg_image->height;
+	bw = bg_image[caching]->width;
+	bh = bg_image[caching]->height;
 	j = 0;
 	if (image->type == IBITMAP) {
   expand:
@@ -1530,7 +1585,7 @@
 	}
 	pl = image->pixlen;
 	p = image->data + image->width * j * pl;
-	bpl = bg_image->pixlen;
+	bpl = bg_image[caching]->pixlen;
 	pd = -1;
 	n = 0;	/* for lint */
 	trans = image->trans;
@@ -1538,18 +1593,19 @@
 	for ( ; j < image->height; j++) {
 		by = (y + j) % bh;
 		bx = x % bw;
-		b = bg_image->data + (bg_image->width * by + bx) * bpl;
+		b = bg_image[caching]->data + (bg_image[caching]->width * by + bx) * bpl;
 		for (i = 0; i < image->width; i++, p += pl, b += bpl, bx++) {
 			if (bx == bw) {
 				bx = 0;
-				b = bg_image->data + bg_image->width * by * bpl;
+				b = bg_image[caching]->data + 
+					bg_image[caching]->width * by * bpl;
 			}
 			if (memToVal(p, pl) != trans)
 				continue;
 			d = memToVal(b, bpl);
 			if (d != pd) {
 				pd = d;
-				n = obj_image_color(image, bg_image, d, &inithist);
+				n = obj_image_color(image, bg_image[caching], d, &inithist);
 				if (n == -1)
 					goto expand;
 			}
@@ -1571,7 +1627,7 @@
 		fprintf(stderr, "  image=%dx%d+%d+%d",
 			image->width, image->height, x, y);
 		if (COMPLEX_BGIMAGE)
-			fprintf(stderr, "  bg_image=%dx%d", bw, bh);
+			fprintf(stderr, "  bg_image[caching]=%dx%d", bw, bh);
 		fprintf(stderr, "\n");
 	}
 	image->trans = -1;	/* XXX: need recalculation to redraw? */
@@ -1612,7 +1668,7 @@
 	}
 	xim = ximageinfo->ximage;
 	if (xim->format == XYBitmap)
-		XSetBackground(display, gcfore, back_color);
+		XSetBackground(display, gcfore, back_color[caching]);
 	XPutImage(display, target, gcfore, xim, 0, 0,
 		x, y, xim->width, xim->height);
 	freeXImage(image, ximageinfo);
@@ -1652,10 +1708,10 @@
 			? state->linewidth
 			: state->width - xpos;
 	height = state->maxascent + state->maxdescent + 1;
-	fore = fore_color;
+	fore = fore_color[caching];
 
 #ifdef RASTERLIB
-	bcolor = back_color;
+	bcolor = back_color[caching];
 	for (obj = state->obj; obj; obj = obj->next) {
 #ifdef VFLIB
 		if (obj->type == O_VFONT)
@@ -1679,7 +1735,7 @@
 			int bpl;
 			XColor col;
 
-			bim = bg_ximageinfo->ximage;
+			bim = bg_ximageinfo[caching]->ximage;
 			bw = bim->width;
 			bh = bim->height;
 			ox = xpos;
@@ -1688,22 +1744,22 @@
 			by = oy % bh;
 			if (bw == 1) {
 				r = g = b = 0;
-				bpl = bg_image->pixlen;
-				bp = bg_image->data + by * bpl;
+				bpl = bg_image[caching]->pixlen;
+				bp = bg_image[caching]->data + by * bpl;
 				for (y = 0;
 				     y < height;
 				     y++, by++, bp += bpl) {
 					if (by == bh)
 						by = 0;
 					p = memToVal(bp, bpl);
-					if (TRUEP(bg_image)) {
+					if (TRUEP(bg_image[caching])) {
 						r += TRUE_RED(p) << 8;
 						g += TRUE_GREEN(p) << 8;
 						b += TRUE_BLUE(p) << 8;
 					} else {
-						r += bg_image->rgb.red[p];
-						g += bg_image->rgb.green[p];
-						b += bg_image->rgb.blue[p];
+						r += bg_image[caching]->rgb.red[p];
+						g += bg_image[caching]->rgb.green[p];
+						b += bg_image[caching]->rgb.blue[p];
 					}
 					p = XGetPixel(bim, 0, by);
 					for (x = 0; x < width; x++)
@@ -1722,7 +1778,7 @@
 #if 0
 			fprintf(stderr, "bim=%dx%d, r=%x, g=%x, b=%x, "
 				"bcolor=%x\n",
-				bg_image->width, bg_image->height,
+				bg_image[caching]->width, bg_image[caching]->height,
 				col.red, col.green, col.blue, bcolor);
 #endif
 			} else {
@@ -1881,8 +1937,8 @@
 			break;
 		}
 	}
-	if (fore != fore_color)
-		XSetForeground(display, gcfore, fore_color);
+	if (fore != fore_color[caching])
+		XSetForeground(display, gcfore, fore_color[caching]);
 	/* ASSERT(state->obj == NULL); */
 	/* ASSERT(state->objlast == NULL); */
 }
@@ -2249,7 +2305,7 @@
 	char *seed;
 
 	seed = x_findseed(state, registry);
-	xfontstruct = x_setfont(seed, char_size, registry, NULL);
+	xfontstruct = x_setfont(seed, char_size[caching], registry, NULL);
 	if (xfontstruct == NULL)
 		return 0;
 
@@ -2341,7 +2397,7 @@
 	/* okay, please wait for a while... */
 	if (!curs)
 		curs = XCreateFontCursor(display, XC_watch);
-	XDefineCursor(display, state->target, curs);
+	XDefineCursor(display, window, curs);
 	XFlush(display);
 
 	/* just for safety */
@@ -2351,8 +2407,8 @@
 	/* grab parameters */
 	dir = cg->ct_direction;
 	numcolor = cg->ct_numcolor;
-	hquality = b_quality;
-	vquality = b_quality;
+	hquality = b_quality[caching];
+	vquality = b_quality[caching];
 
 	/*
 	 * XXX zoomflag is too complex to understand.
@@ -2411,7 +2467,7 @@
 
 	/* performace enhance hack for special case */
 	if (dir % 90 == 0) {
-		int *p, *q;
+		int *p, *q, *r;
 
 		/*
 		 * 0 or 180: reduce width
@@ -2419,10 +2475,12 @@
 		 */
 		p = (dir % 180 == 0) ? &srcwidth : &srcheight;
 		q = (dir % 180 == 0) ? &xzoomrate : &yzoomrate;
+		r = (dir % 180 == 0) ? &dstwidth : &dstheight;
 
 		/* rely upon use X11 background image tiling. */
 		*p = 1;
 		*q = 100;
+		*r = 1;
 	}
 
 	if (verbose) {
@@ -2478,17 +2536,23 @@
 	}
 
 	/* draw background */
-	XSetWindowBackgroundPixmap(display, state->target, mypixmap);
+	if (!caching) 
+		XSetWindowBackgroundPixmap(display, state->target, mypixmap);
+	else  
+		XSetPixmapBackgroundPixmap(display, state->target, 
+			mypixmap, ximageinfo->ximage->width, ximageinfo->ximage->height);
 
 	/* finish */
 	XFreePixmap(display, mypixmap);
-	if (bg_image) {
-		freeXImage(bg_image, bg_ximageinfo);
-		freeImage(bg_image);
-	}
-	bg_ximageinfo = ximageinfo;
-	bg_image = myimage;
-	XUndefineCursor(display, state->target);
+
+	if (bg_image[caching]) {
+		freeXImage(bg_image[caching], bg_ximageinfo[caching]);
+		freeImage(bg_image[caching]);
+	}
+	bg_ximageinfo[caching] = ximageinfo;
+	bg_image[caching] = myimage;
+
+	XUndefineCursor(display, window);
 	XFlush(display);
 }
 
@@ -2514,10 +2578,12 @@
 	static char backfile[MAXPATHLEN];
 	static int backzoom, backnumcolor, backx, backy;
 
-	if (!curs)
-		curs = XCreateFontCursor(display, XC_watch);
-	XDefineCursor(display, state->target, curs);
-	XFlush(display);
+	if (!caching){
+		if (!curs)
+			curs = XCreateFontCursor(display, XC_watch);
+		XDefineCursor(display, state->target, curs);
+		XFlush(display);
+	}
 
 	if ((myimage = loadImage(filename, verbose)) == NULL) {
 		fprintf(stderr, "failed to load image file\n");
@@ -2530,7 +2596,7 @@
 		XColor xc;
 
 		xc.flags = DoRed | DoGreen | DoBlue;
-		xc.pixel = fore_color;
+		xc.pixel = fore_color[caching];
 		XQueryColor(display, colormap, &xc);
 		*(myimage->rgb.red + 1) = xc.red;
 		*(myimage->rgb.green + 1) = xc.green;
@@ -2605,25 +2671,34 @@
 			fprintf(stderr, "Cannot create image in server\n");
 			cleanup(-1);
 		}
-		XSetWindowBackgroundPixmap(display, state->target, mypixmap);
+
+		if (!caching)
+			XSetWindowBackgroundPixmap(display, state->target, mypixmap);
+		else  {
+			XSetPixmapBackgroundPixmap(display, state->target, mypixmap,
+				ximageinfo->ximage->width, ximageinfo->ximage->height);
+		}
+
 		XFreePixmap(display, mypixmap);
 		strcpy(backfile, filename);
 		backnumcolor = numcolor;
 		backzoom = zoomflag;
 		backx = ximagesize;
 		backy = yimagesize;
-		if (bg_image) {
-			freeXImage(bg_image, bg_ximageinfo);
-			freeImage(bg_image);
+
+		if (bg_image[caching]) {
+			freeXImage(bg_image[caching], bg_ximageinfo[caching]);
+			freeImage(bg_image[caching]);
 		}
-		bg_ximageinfo = ximageinfo;
-		bg_image = myimage;
+		bg_ximageinfo[caching] = ximageinfo;
+		bg_image[caching] = myimage;
+
 		goto end;
 	}
 
 	draw_line_itemsize(state, 0, height * yzoomrate / 100);
 	if (centerflag)
-		image_posx = char_size / 2 - (width * xzoomrate / 100) / 2;
+		image_posx = char_size[caching] / 2 - (width * xzoomrate / 100) / 2;
 	else
 		image_posx = 0;
 
@@ -2632,8 +2707,10 @@
 		myimage, xzoomrate, yzoomrate);
 	state->linewidth += (width * xzoomrate / 100);
 end:
-	XUndefineCursor(display, state->target);
-	XFlush(display);
+	if (!caching){
+		XUndefineCursor(display, state->target);
+		XFlush(display);
+	}
 }
 
 static void
@@ -2746,7 +2823,7 @@
 	int pos, n, p, barlen;
 	GC *pgc;
 
-	if (t_start == 0 || tbar_mode == 0)
+	if (t_start == 0 || tbar_mode == 0 || caching)
 		return;
 
 	pos = (state->width - 2) * (state->page - 1) / (maxpage - 1);
@@ -2821,7 +2898,7 @@
 	}
 
 	icon_type = icon_words[i].ctl_type; /* may be 0 */
-	icon_size = char_size * cp->ctic_size / 100;
+	icon_size = char_size[caching] * cp->ctic_size / 100;
 
 	switch(icon_type){
 	case 0:
@@ -2830,28 +2907,28 @@
 		icon_y = icon_size * 100 / state->height;
 		if (icon_x == 0) icon_x = 1;
 		if (icon_y == 0) icon_y = 1;
-		tmp_color = fore_color;
-		fore_color = cp->ctic_color;
+		tmp_color = fore_color[caching];
+		fore_color[caching] = cp->ctic_color;
 		image_load(state, cp->ctic_value, 0, icon_x, icon_y, 0, 0, 1);
-		fore_color = tmp_color;
+		fore_color[caching] = tmp_color;
 		break;
 
 	case 1:
 		/* this is box */
 		obj_new_icon(state,
-			state->linewidth + char_size/2 - icon_size/2,
+			state->linewidth + char_size[caching]/2 - icon_size/2,
 			POSY(icon_size), icon_type, icon_size,
 			cp->ctic_color, 0, NULL);
-		state->linewidth += char_size;
+		state->linewidth += char_size[caching];
 		break;
 
 	case 2:
 		/* this is arc */
 		obj_new_icon(state,
-			state->linewidth + char_size/2 - icon_size/2,
+			state->linewidth + char_size[caching]/2 - icon_size/2,
 			POSY(icon_size), icon_type, icon_size, 
 			cp->ctic_color, 0, NULL);
-		state->linewidth += char_size;
+		state->linewidth += char_size[caching];
 		break;
 
 	case 3:
@@ -2860,7 +2937,7 @@
 	case 6:
 	case 7:
 		index = icon_type - 3;
-		icon_x = state->linewidth + (char_size - icon_size) / 2;
+		icon_x = state->linewidth + (char_size[caching] - icon_size) / 2;
 #if 0
 		icon_y = POSY(icon_size);
 #else
@@ -2874,7 +2951,7 @@
 		}
 		obj_new_icon(state, 0, 0, icon_type, icon_size, 
 			cp->ctic_color, icon_point[index].point_num, xpoint);
-		state->linewidth += char_size;
+		state->linewidth += char_size[caching];
 		break;
 
 	default:
@@ -2902,7 +2979,7 @@
 	}
 	col.pixel = cp->ctb_color;
 	if (col.pixel == -1)
-		col.pixel = fore_color;
+		col.pixel = fore_color[caching];
 	if (col.pixel != prevcolor) {
 		prevcolor = col.pixel;
 		col.flags = DoRed|DoGreen|DoBlue;
@@ -2923,7 +3000,7 @@
 	XFillRectangle(display, state->target, gcbar, st, state->ypos, len, width);
 	XFillRectangle(display, state->target, gcsbar, st, state->ypos + width, len, swidth);
 
-	state->ypos += width + swidth + VERT_GAP(char_size) / 2;
+	state->ypos += width + swidth + VERT_GAP(char_size[caching]) / 2;
 }
 
 static void
@@ -3260,7 +3337,7 @@
 	struct render_state *state;
 {
 	/* invalidate the background image cache */
-	bg_image_prev = NULL;
+	bg_image_prev[0] = NULL;
 	x_registerseed(state, NULL, NULL);
 }
 
@@ -3496,7 +3573,7 @@
 		 * XXX: Actually, no one comes here.
 		 *      This translation for IBITMAP was done by image_load().
 		 */
-		fore.pixel = fore_color;
+		fore.pixel = fore_color[caching];
 		fore.flags = DoRed | DoGreen | DoBlue;
 		XQueryColor(display, colormap, &fore);
 		image->rgb.red  [1] = fore.red;
@@ -3515,12 +3592,12 @@
 		}
 		/* grayscale */
 
-		fore.pixel = fore_color;
+		fore.pixel = fore_color[caching];
 		fore.flags = DoRed | DoGreen | DoBlue;
 		XQueryColor(display, colormap, &fore);
 
 		if (!COMPLEX_BGIMAGE) {
-			back.pixel = back_color;
+			back.pixel = back_color[caching];
 			back.flags = DoRed | DoGreen | DoBlue;
 			XQueryColor(display, colormap, &back);
 		} else {
@@ -3529,19 +3606,20 @@
 			Pixel d;
 
 			/* XXX: use background color of center position */
-			x = (obj->x + image->width/2) % bg_image->width;
-			y = (state->ypos + image->height/2) % bg_image->height;
-			bpl = bg_image->pixlen;
-			p = bg_image->data + (bg_image->width * y + x) * bpl;
+			x = (obj->x + image->width/2) % bg_image[caching]->width;
+			y = (state->ypos + image->height/2) % bg_image[caching]->height;
+			bpl = bg_image[caching]->pixlen;
+			p = bg_image[caching]->data 
+				+ (bg_image[caching]->width * y + x) * bpl;
 			d = memToVal(p, bpl);
-			if (bg_image->type == ITRUE) {
+			if (bg_image[caching]->type == ITRUE) {
 				back.red   = TRUE_RED(d) << 8;
 				back.green = TRUE_GREEN(d) << 8;
 				back.blue  = TRUE_BLUE(d) << 8;
 			} else {
-				back.red   = bg_image->rgb.red  [d];
-				back.green = bg_image->rgb.green[d];
-				back.blue  = bg_image->rgb.blue [d];
+				back.red   = bg_image[caching]->rgb.red  [d];
+				back.green = bg_image[caching]->rgb.green[d];
+				back.blue  = bg_image[caching]->rgb.blue [d];
 			}
 		}
 		for (i = 0; i < image->rgb.used; i++) {
@@ -3712,3 +3790,157 @@
 	}
 	return "*-*-*";		/*anything, canonicalized*/
 }
+
+static void 
+XSetPixmapBackground(display, target, bgcolor)
+	Display *display;
+	Drawable target;
+	u_long	bgcolor;
+{
+	XSetForeground(display, gc_cache, bgcolor);
+	XFillRectangle(display, cacheback,
+		gc_cache, 0, 0, window_width, window_height);
+}
+
+static void 
+XSetPixmapBackgroundPixmap(display, target, pixmap, width, height)
+	Display *display;
+	Drawable target;
+	Pixmap	pixmap;
+	int	width, height;
+{
+	int	x, y;
+
+	for (y = 0; y < window_height; y += height)
+		for (x = 0; x < window_width; x += width){
+			XCopyArea(display, pixmap, cacheback, gc_cache, 0, 0,
+				width, height, x, y);
+		}
+}
+
+static void 
+XClearPixmap(display, target)
+	Display *display;
+	Drawable target;
+{
+	XCopyArea(display, cacheback, cachewin, gc_cache, 
+			0, 0, window_width, window_height, 0, 0);
+}
+
+/* cache specified page */
+static void
+cache_page(state, page)
+	struct render_state *state;
+	int page;
+{
+	/* we don't need caching */
+	if (cached_page == page || page > maxpage || page <= 0)
+		return;
+
+	XFlush(display);
+	memset(state, 0, sizeof(struct render_state));
+	state->target = cachewin;  /*XXX*/
+	state->width = window_width;
+	state->height = window_height;
+	state->page = page;
+	caching = 1;
+	if (verbose){
+		printf("now caching %d page ...\n", page);
+		fflush(stdout);
+	}
+	draw_page(state, NULL);
+	if (verbose){
+		printf("caching done \n");
+	}
+	caching = 0;
+	cached_page = page;
+}
+
+static void
+set_from_cache(state)
+	struct render_state *state;
+{
+	char_size[0] = char_size[1];
+	horiz_gap[0] = horiz_gap[1];
+	vert_gap[0] = vert_gap[1];
+	fore_color[0] = fore_color[1];
+	back_color[0] = back_color[1];
+	ctrl_color[0] = ctrl_color[1];
+	b_quality[0] = b_quality[1];
+
+	bg_image_ctl[0] = bg_image_ctl[1];
+	bg_image_prev[0] = bg_image_prev[1];
+	bg_image[0] = bg_image[1];
+	bg_ximageinfo[0] = bg_ximageinfo[1];
+
+	bg_image_ctl[1] = NULL;
+	bg_image_prev[1] = NULL;
+	bg_image[1] = NULL;
+	bg_ximageinfo[1] = NULL;
+
+	memcpy(state, &cache_state, sizeof(struct render_state));	
+	state->target = window;
+
+	XSetForeground(display, gcfore, fore_color[0]);
+	XSetBackground(display, gcfore, back_color[0]);
+	XCopyArea(display, cacheback, cachetmpback, gc_cache,
+                  0, 0,  window_width, window_height, 0, 0);
+	XSetWindowBackgroundPixmap(display, state->target, cachetmpback);
+
+	switch(cache_effect){
+		case 1:
+			cache_effect1();
+			break;
+		case 2:
+			cache_effect2();
+			break;
+		default:
+			break;
+	}
+	XCopyArea(display, cachewin, window, gc_cache, 
+		0, 0, window_width, window_height, 0, 0);
+	XFlush(display);
+}
+
+void
+reset_cache_bgimage()
+{
+	bg_image_ctl[1] = NULL;
+	bg_image_prev[1] = NULL;
+	bg_image[1] = NULL;
+	bg_ximageinfo[1] = NULL;
+}
+
+static void
+cache_effect1()
+{
+	int x, step = window_width / 30; /* XXX */
+
+	for (x = window_width; x > 0; x -= step){
+		XCopyArea(display, window, window, gc_cache,
+			step, 0,  window_width - step, window_height, 0, 0);
+
+		XCopyArea(display, cachewin, window, gc_cache,
+			window_width - x, 0, step, window_height, 
+			window_width - step, 0);
+
+		XFlush(display);
+	}
+}
+
+static void
+cache_effect2()
+{
+	int x, step = window_width / 60; /* XXX */
+
+	for (x = 0; x < window_width; x += step){
+		XCopyArea(display, window, window, gc_cache,
+			x, 0,  window_width - step -x , window_height, x + step, 0);
+
+		XCopyArea(display, cachewin, window, gc_cache,
+			x, 0, step, window_height, x, 0);
+
+		XFlush(display);
+	}
+}
+
Index: kit/font.c
diff -u kit/font.c:1.22 kit/font.c:1.23
--- kit/font.c:1.22	Mon Feb  1 11:52:56 1999
+++ kit/font.c	Sun May 16 00:50:26 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: font.c,v 1.22 1999/02/01 02:52:56 onoe Exp $
+ * $Id: font.c,v 1.23 1999/05/15 15:50:26 nishida Exp $
  */
 
 #include "mgp.h"
@@ -394,8 +394,12 @@
 		if (prev_vfcap == NULL)
 			prev_vfcap = "";	/* XXX: just in case */
 	}
+
+#if 0
 	if (vfont_fd >= 0)
 		VF_CloseFont(vfont_fd);
+#endif 
+
 	vfont_fd = VF_OpenFont(fontname);
 	vf_curname = fontname;
 	if (vfont_fd < 0) {
Index: kit/globals.c
diff -u kit/globals.c:1.35 kit/globals.c:1.36
--- kit/globals.c:1.35	Mon Apr 12 03:14:18 1999
+++ kit/globals.c	Sun May 16 00:50:28 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: globals.c,v 1.35 1999/04/11 18:14:18 nishida Exp $
+ * $Id: globals.c,v 1.36 1999/05/15 15:50:28 nishida Exp $
  */
 
 #include "mgp.h"
@@ -59,19 +59,27 @@
 int screen;
 int window_width;
 int window_height;
+int caching = 0;
+int cached_page = 0;
+int cache_hit = 0;
+int cache_mode = 0;
+int cache_effect = 0;
 Pixmap pixmap;
+Pixmap cachewin;
+Pixmap cacheback;
+Pixmap cachetmpback;
 Colormap colormap;
 int free_clr_num;
 u_long *free_clr = NULL;
 
-u_int char_size;
-u_int horiz_gap = DEFAULT_HGAP;
-u_int vert_gap = DEFAULT_VGAP;
+u_int char_size[2];
+u_int horiz_gap[2] = {DEFAULT_HGAP, DEFAULT_HGAP};
+u_int vert_gap[2] = {DEFAULT_VGAP, DEFAULT_VGAP};
 u_int depth;
-u_long fore_color;
-u_long back_color;
-u_long ctrl_color;
-u_int b_quality = DEFAULT_BQUALITY;
+u_long fore_color[2];
+u_long back_color[2];
+u_long ctrl_color[2];
+u_int b_quality[2] = {DEFAULT_BQUALITY, DEFAULT_BQUALITY};
 u_int quality_flag = 0;
 
 struct alloc_color image_clr = {0, NULL};
Index: kit/keywords.pl
diff -u kit/keywords.pl:1.1 kit/keywords.pl:removed
--- kit/keywords.pl:1.1	Tue Nov 11 15:07:40 1997
+++ kit/keywords.pl	Mon May 17 05:10:12 1999
@@ -1,14 +0,0 @@
-@keywords = ();
-
-die if (@ARGV != 1);
-open(IN, "< $ARGV[0]") || die;
-while (<IN>) {
-	next if (! /^\/\*CTL\*\//);
-	next if (! /CTL_([A-Z0-9]+),/);
-	$t = $1;
-	$t =~ tr/A-Z/a-z/;
-	push(@keywords, $t);
-}
-close(IN);
-
-print join(' ', @keywords) . "\n";
Index: kit/mgp.c
diff -u kit/mgp.c:1.97 kit/mgp.c:1.99
--- kit/mgp.c:1.97	Mon Apr 26 01:34:40 1999
+++ kit/mgp.c	Sun May 16 02:39:40 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: mgp.c,v 1.97 1999/04/25 16:34:40 itojun Exp $
+ * $Id: mgp.c,v 1.99 1999/05/15 17:39:40 nishida Exp $
  */
 
 static char *mgp_version = "1.04a (980906)";
@@ -184,6 +184,8 @@
 		sigprocmask(SIG_UNBLOCK, &mask, NULL);
 		kill(mypid, sig);
 	}
+
+	finish_win(); /* finish X connection */
 	exit(-sig);
 }
 
@@ -213,7 +215,7 @@
 		mgpwdir = p;
 	}
 
-#define ACCEPTOPTS	"BdvVob:c:eg:f:hlGp:qt:Q:PST:D:CORw:X:x:n"
+#define ACCEPTOPTS	"BdvVob:c:eg:f:hlGp:qt:Q:PST:D:CORw:X:x:nF:"
 	while ((opt = getopt(argc, argv, ACCEPTOPTS)) != -1) {
 #undef ACCEPTOPTS
 		switch (opt) {
@@ -279,7 +281,7 @@
 			break;
 
 		case 'Q':
-			b_quality = atoi(optarg);
+			b_quality[caching] = atoi(optarg);
 			quality_flag = 1;
 			break;
 
@@ -338,6 +340,13 @@
 		case 'n':
 			mgp_flag |= FL_NOSTDIN;
 			break;
+
+		case 'F':
+			mgp_flag |= FL_FRDCACHE;
+			cache_mode = atoi(optarg)%10;
+			cache_effect = atoi(optarg)/10;
+			break;
+
 		case 'h':
 		default:
 			mgp_usage(progname);
@@ -678,6 +687,7 @@
 			XDefineCursor(display, window, pen_curs);
 		else
 			XUndefineCursor(display, window);
+
 		do {
 			; /*nothing*/
 		} while (draw_one(&state, &e) == False);
@@ -714,6 +724,7 @@
 		}
 
 		prevpage = state.page;
+
 		switch (e.type) {
 		case EnterNotify:
 			for (i = 1; i <= maxpage; i++) {
@@ -818,12 +829,11 @@
 
 				if (number == 0)
 					number = 1;
-				if (state.cp && state.cp->ct_op == CTL_PAUSE)
+				if (state.cp && state.cp->ct_op == CTL_PAUSE){
 					state_next(&tstate);
-				else if (state.page + number
+				} else if (state.page + number
 						<= maxpage) {
-					state_goto(&tstate,
-						state.page + number, 0);
+						state_goto(&tstate, state.page + number, 0);
 				} else {
 					beep();
 					break;
@@ -963,6 +973,16 @@
 				number = number * 10 + key - XK_0;
 				break;
 
+            case XK_c:
+				if (verbose) 
+					if (mgp_flag & FL_FRDCACHE)
+						printf("turn off forward cache\n");
+					else			
+						printf("turn on forward cache\n");
+
+				mgp_flag ^= FL_FRDCACHE;
+                break;
+
 			default:
 				number = 0;
 				break;
@@ -1023,10 +1043,16 @@
 				window_height = e.xconfigure.height;
 				state.width = e.xconfigure.width;
 				state.height = e.xconfigure.height;
+				if (mgp_flag & FL_FRDCACHE) {
+					cached_page = 0;
+					reset_cache_pixmap();
+					reset_cache_bgimage();
+				}
 				draw_reinit(&state);	/*notify*/
 				lastcp = state.cp;
 				state_goto(&state, state.page, 1);
 				draw_page(&state, lastcp);
+
 			}
 			if (pg_mode) {
 				pg_on();
Index: kit/mgp.h
diff -u kit/mgp.h:1.105 kit/mgp.h:1.106
--- kit/mgp.h:1.105	Sat Apr 24 11:43:03 1999
+++ kit/mgp.h	Sun May 16 00:50:30 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: mgp.h,v 1.105 1999/04/24 02:43:03 itojun Exp $
+ * $Id: mgp.h,v 1.106 1999/05/15 15:50:30 nishida Exp $
  */
 
 #include <stdio.h>
@@ -165,6 +165,7 @@
 #define FL_NOFREETYPE	0x1000
 #define	FL_NOSTDIN	0x2000
 #define	FL_GLYPHEDGE	0x4000
+#define	FL_FRDCACHE		0x8000
 
 /* 	page attribute flags 	*/
 #define PGFLAG_NODEF	0x01	/* nodefault */
@@ -330,6 +331,12 @@
 };
 extern struct page_attribute page_attribute[MAXPAGE];
 
+extern int	caching;
+extern int	cached_page;
+extern int	cache_hit;
+extern int	cache_mode;
+extern int	cache_effect;
+
 struct render_state {
 	/* state of the parser */
 	u_int page;
@@ -492,24 +499,27 @@
 extern int window_width;
 extern int window_height;
 extern Pixmap pixmap;
+extern Pixmap cachewin;
+extern Pixmap cacheback;
+extern Pixmap cachetmpback;
 extern Colormap colormap;
 extern struct alloc_color image_clr;
 extern struct alloc_color back_clr;
 extern struct alloc_color font_clr;
 
-extern u_int char_size;
-extern u_int horiz_gap;
-extern u_int vert_gap;
+extern u_int char_size[2];
+extern u_int horiz_gap[2];
+extern u_int vert_gap[2];
 extern u_int depth;
 extern Visual *visual;
-extern u_long fore_color;
-extern u_long back_color;
-extern u_long ctrl_color;
-extern u_int b_quality;
+extern u_long fore_color[2];
+extern u_long back_color[2];
+extern u_long ctrl_color[2];
+extern u_int b_quality[2];
 extern u_int quality_flag;
 
-#define VERT_GAP(s)		((s) * vert_gap / 100)
-#define HORIZ_GAP(s)		((s) * horiz_gap / 100)
+#define VERT_GAP(s)		((s) * vert_gap[caching] / 100)
+#define HORIZ_GAP(s)		((s) * horiz_gap[caching] / 100)
 #define VERT_STEP(s)		((s) + VERT_GAP(s))
 #define HORIZ_STEP(s, x)	((x) + HORIZ_GAP(s))
 
@@ -532,6 +542,8 @@
 extern GC gc_pta;
 extern GC gc_ptk;
 
+extern GC gc_cache;
+
 extern long xeventmask;
 
 /*
@@ -625,6 +637,7 @@
 extern void init_win1 __P((char *));
 extern void init_win2 __P((void));
 extern void init_win3 __P((void));
+extern void finish_win __P((void));
 extern int get_color __P((char *, u_long *));
 extern struct g_color *name2gcolor __P((char *));
 extern void regist_alloc_colors __P((struct alloc_color *, u_long *, int));
Index: kit/plist.c
diff -u kit/plist.c:1.20 kit/plist.c:1.21
--- kit/plist.c:1.20	Sun Mar  7 02:30:48 1999
+++ kit/plist.c	Sun May 16 00:50:32 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: plist.c,v 1.20 1999/03/06 17:30:48 nishida Exp $
+ * $Id: plist.c,v 1.21 1999/05/15 15:50:32 nishida Exp $
  */
 
 #include "mgp.h"
@@ -66,7 +66,7 @@
 	pl_y = window_height - (pl_ny + 1) * pl_fh - (t_fin ? 5 : 0);
 	pl_titlewin = XCreateSimpleWindow(display, window,
 		0, pl_y - pl_fh, window_width, pl_fh, 0,
-		BlackPixel(display, 0), back_color);
+		BlackPixel(display, 0), back_color[caching]);
 	XSelectInput(display, pl_titlewin, StructureNotifyMask);
 
 	for (i = 1; i <= maxpage; i++) {
@@ -152,10 +152,10 @@
 	if (page == 0)
 		return;
 	sprintf(buf, "page %d: %s", page, page_title(page));
-	XSetForeground(display, gc_pta, ctrl_color);
-	XSetForeground(display, gc_ptk, ctrl_color);
-	XSetBackground(display, gc_pta, back_color);
-	XSetBackground(display, gc_ptk, back_color);
+	XSetForeground(display, gc_pta, ctrl_color[caching]);
+	XSetForeground(display, gc_ptk, ctrl_color[caching]);
+	XSetBackground(display, gc_pta, back_color[caching]);
+	XSetBackground(display, gc_ptk, back_color[caching]);
 	draw_kstring(pl_titlewin, buf,
 		PL_X_MARGIN, pl_fh - plfs->max_bounds.descent);
 }
@@ -200,7 +200,7 @@
 	pg_win = XCreateSimpleWindow(display, window,
 		0, window_height - pl_fh - (t_fin ? 5 : 0),
 		window_width, pl_fh, 0,
-		BlackPixel(display, screen), back_color);
+		BlackPixel(display, screen), back_color[caching]);
 	XSelectInput(display, pg_win, StructureNotifyMask);
 	XMapSubwindows(display, window);
 
@@ -244,10 +244,10 @@
 	}
 
 	showlast = (state->cp->ct_op == CTL_PAUSE && state->cp->cti_value);
-	XSetForeground(display, gc_pta, ctrl_color);
-	XSetForeground(display, gc_ptk, ctrl_color);
-	XSetBackground(display, gc_pta, back_color);
-	XSetBackground(display, gc_ptk, back_color);
+	XSetForeground(display, gc_pta, ctrl_color[caching]);
+	XSetForeground(display, gc_ptk, ctrl_color[caching]);
+	XSetBackground(display, gc_pta, back_color[caching]);
+	XSetBackground(display, gc_ptk, back_color[caching]);
 
 	pg_clean();
 	if (page > 1) {
Index: kit/print.c
diff -u kit/print.c:1.78 kit/print.c:1.79
--- kit/print.c:1.78	Fri Apr 23 19:28:20 1999
+++ kit/print.c	Sun May 16 00:50:33 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: print.c,v 1.78 1999/04/23 10:28:20 itojun Exp $
+ * $Id: print.c,v 1.79 1999/05/15 15:50:33 nishida Exp $
  */
 /*
  * Paper size selection code is based on psutil.c by Angus J. C. Duggan
@@ -283,7 +283,7 @@
 	window_width  = w_width;
 	window_height = w_height;
 
-	char_size = window_height * DEFAULT_CHARSIZE / 100;
+	char_size[0] = window_height * DEFAULT_CHARSIZE / 100;
 
 	if (outputfile[0]) {
 		if ((fp = fopen(outputfile, "w")) == NULL) {
@@ -571,7 +571,7 @@
 
 	switch(cp->ct_op) {
 	case CTL_SIZE:
-		char_size = window_height * cp->ctf_value / 100;
+		char_size[0] = window_height * cp->ctf_value / 100;
 		fprintf(fp, "%d setcharsize\n", char_size);
 		break;
 
@@ -620,17 +620,17 @@
 		exit(1);
 
 	case CTL_VGAP:
-		vert_gap = cp->cti_value;
+		vert_gap[0] = cp->cti_value;
 		fprintf(fp, "/vertgap %d def\n", cp->cti_value);
 		break;
 
 	case CTL_HGAP:
-		horiz_gap = cp->cti_value;
+		horiz_gap[0] = cp->cti_value;
 		fprintf(fp, "/horizgap %d def\n", cp->cti_value);
 		break;
 
 	case CTL_GAP:
-		vert_gap = horiz_gap = cp->cti_value;
+		vert_gap[0] = horiz_gap[0] = cp->cti_value;
 		fprintf(fp, "/vertgap %d def ", cp->cti_value);
 		fprintf(fp, "/horizgap %d def\n", cp->cti_value);
 		break;
@@ -1018,7 +1018,7 @@
 	fprintf(fp, "%d %d rlineto\n", 0, pbar.ct_width);
 	fprintf(fp, "%d %d rlineto stroke\n", pbar.ct_length * -1, 0);
 	fprintf(fp, "/ypos ypos %d sub def\n",
-		cp->ctb_width + VERT_GAP(char_size) / 2);
+		cp->ctb_width + VERT_GAP(char_size[0]) / 2);
 	fprintf(fp, "xpos ypos moveto\n");
 
 	linewidth = 0;
@@ -1047,9 +1047,9 @@
 				break;
 	}
 	itype = icon_words[i].ctl_type;
-	isize = char_size * cp->ctic_size / 100;
+	isize = char_size[0] * cp->ctic_size / 100;
 	icon_remember(itype, isize, linewidth, cp->ctic_color);
-	linewidth += char_size;
+	linewidth += char_size[0];
 }
 
 static void
@@ -1162,7 +1162,7 @@
 		buf[0] = OPENBRACE(kanjimode);
 		*q++ = CLOSEBRACE(kanjimode);
 		*q = '\0';
-		text_remember(buf, KANJI, char_size, textstartpos, pfx);
+		text_remember(buf, KANJI, char_size[0], textstartpos, pfx);
 	} else {
 		/* must take care of escaping those "dangerous" letters */
 		q = &buf[0];
@@ -1175,7 +1175,7 @@
 		}
 		*q++ = CLOSEBRACE(kanjimode);
 		*q++ = '\0';
-		text_remember(buf, ASCII, char_size, textstartpos, pfx);
+		text_remember(buf, ASCII, char_size[0], textstartpos, pfx);
 	}
 }
 
@@ -1240,7 +1240,7 @@
 {
 	textpool[ntextpool].pfx = 1;
 	textpool[ntextpool].xoffset = offset;
-	textpool[ntextpool].xsiz = char_size;
+	textpool[ntextpool].xsiz = char_size[0];
 	textpool[ntextpool].size = fontsize;
 	textpool[ntextpool].font = (struct fontmap *)icon;	/*XXX*/
 	textpool[ntextpool].text = NULL;
Index: kit/tfont.c
diff -u kit/tfont.c:1.29 kit/tfont.c:1.30
--- kit/tfont.c:1.29	Sat Apr 24 11:43:04 1999
+++ kit/tfont.c	Sun May 16 00:58:08 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: tfont.c,v 1.29 1999/04/24 02:43:04 itojun Exp $
+ * $Id: tfont.c,v 1.30 1999/05/15 15:58:08 nishida Exp $
  */
 
 #include "mgp.h"
@@ -355,7 +355,7 @@
 		tf_mcurname = tfloadedfont[tfcuridx];
 	else
 		tf_curname = tfloadedfont[tfcuridx];
-	if (tfc_setsize(char_size) < 0)
+	if (tfc_setsize(char_size[caching]) < 0)
 		goto fail2;
 
 	/* success */
@@ -426,7 +426,7 @@
 	}
 
 	/* This is required! */
-	if (tfc_setsize(char_size) < 0)
+	if (tfc_setsize(char_size[caching]) < 0)
 		return NULL;
 
 	tfc = (struct tfont *)malloc(sizeof(*tfc));
Index: kit/x11.c
diff -u kit/x11.c:1.21 kit/x11.c:1.23
--- kit/x11.c:1.21	Mon Dec 21 15:31:53 1998
+++ kit/x11.c	Sun May 16 02:39:41 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: x11.c,v 1.21 1998/12/21 06:31:53 onoe Exp $
+ * $Id: x11.c,v 1.23 1999/05/15 17:39:41 nishida Exp $
  */
 
 #include "mgp.h"
@@ -44,6 +44,9 @@
 GC gc_pta;
 GC gc_ptk;
 
+/* for caching */
+GC gc_cache;
+
 long xeventmask = EVENT_DEFAULT | EVENT_RAKUGAKI;
 
 static u_long zero = 0;
@@ -55,7 +58,7 @@
 	u_long *back;
 	char *color;
 } gcconf[]  = {
-	{ &gcfore,	GXcopy, &fore_color, &zero },
+	{ &gcfore,	GXcopy, &fore_color[0], &zero },
 	{ &gcpen,	GXcopy, NULL, NULL, "red" },
 	{ &gcred,	GXcopy, NULL, NULL, "red" },
 	{ &gcgreen,	GXcopy, NULL, NULL, "green" },
@@ -195,11 +198,11 @@
 			colormap = XCopyColormapAndFree(display, colormap);
 	}
 
-	char_size = window_height * DEFAULT_CHARSIZE / 100;
-	(void)get_color(DEFAULT_FORE, &fore_color);
-	ctrl_color = fore_color;
+	char_size[0] = window_height * DEFAULT_CHARSIZE / 100;
+	(void)get_color(DEFAULT_FORE, &fore_color[0]);
+	ctrl_color[0] = fore_color[0];
 
-	(void)get_color(back_clname, &back_color);
+	(void)get_color(back_clname, &back_color[0]);
 }
 
 void
@@ -212,8 +215,8 @@
 	u_long color;
 	XClassHint res = { "MagicPoint", "MagicPoint" };
 
-	xsa.border_pixel = fore_color;
-	xsa.background_pixel = back_color;
+	xsa.border_pixel = fore_color[0];
+	xsa.background_pixel = back_color[0];
 	xsa.backing_store = Always;
 	xsa.colormap = colormap;
 	mask = CWBorderPixel | CWBackPixel | CWBackingStore | CWColormap;
@@ -232,6 +235,10 @@
 	XSetClassHint(display, window, &res);
 	pixmap = XCreatePixmap(display, window, xa.width, xa.height, depth);
 	maskpix = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	cachewin = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	cacheback = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	cachetmpback = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	gc_cache = XCreateGC(display, window, 0, 0);
 
 	for (pc = &gcconf[0]; pc->gc; pc++) {
 		*pc->gc = XCreateGC(display, window, 0, 0);
@@ -322,6 +329,14 @@
 
 }
 
+void
+finish_win()
+{
+	XUngrabKeyboard(display, CurrentTime);	
+	XUngrabPointer(display, CurrentTime);	
+	XCloseDisplay(display);	
+}
+
 int
 get_color(colorname, value)
 	char *colorname;
@@ -390,4 +405,16 @@
 	for (i = 0; i < num; i++)
 		clr->colors[clr->num +i] = (u_long)*(colors +i);
 	clr->num += num;
+}
+
+void
+reset_cache_pixmap()
+{
+	XFreePixmap(display, cachewin);
+	XFreePixmap(display, cacheback);
+	XFreePixmap(display, cachetmpback);
+
+	cachewin = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	cacheback = XCreatePixmap(display, window, xa.width, xa.height, depth);
+	cachetmpback = XCreatePixmap(display, window, xa.width, xa.height, depth);
 }
Index: kit/x11dummy.c
diff -u kit/x11dummy.c:1.11 kit/x11dummy.c:1.12
--- kit/x11dummy.c:1.11	Mon Dec 21 15:31:54 1998
+++ kit/x11dummy.c	Sun May 16 00:50:36 1999
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  */
 /*
- * $Id: x11dummy.c,v 1.11 1998/12/21 06:31:54 onoe Exp $
+ * $Id: x11dummy.c,v 1.12 1999/05/15 15:50:36 nishida Exp $
  */
 
 #include "mgp.h"
@@ -61,7 +61,7 @@
 	}
 
 	window = XCreateSimpleWindow(display, RootWindow(display, 0),
-		0, 0, 800, 600, 0, fore_color, back_color);
+		0, 0, 800, 600, 0, fore_color[0], back_color[0]);
 
 	pixmap  = XCreatePixmap(display, window,
 		window_width, window_height, depth);
@@ -73,6 +73,12 @@
 	XChangeWindowAttributes(display, window, mask, &xsa);
 
 	XFlush(display);
+}
+
+void
+finish_win()
+{
+	XCloseDisplay(display);
 }
 
 #if 0
Index: kit/sample/default.mgp
diff -u kit/sample/default.mgp:1.17 kit/sample/default.mgp:1.18
--- kit/sample/default.mgp:1.17	Fri Sep  4 18:09:39 1998
+++ kit/sample/default.mgp	Sat May 15 14:15:31 1999
@@ -15,9 +15,9 @@
 %%
 %% see README.fonts{,.jp} for more detailed milage you take.
 %%
-%deffont "standard" xfont "helvetica-medium-r", vfont "goth", tfont "arial.ttf"
-%deffont "thick" xfont "helvetica-bold-r", vfont "goth", tfont "arialbd.ttf"
-%deffont "typewriter" xfont "courier-medium-r", vfont "goth", tfont "courbd.ttf"
+%deffont "standard" xfont "helvetica-medium-r", vfont "goth", tfont "arial.ttf", tmfont "wadalab-gothic.ttf"
+%deffont "thick" xfont "helvetica-bold-r", vfont "goth", tfont "arialbd.ttf", tmfont "wadalab-gothic.ttf"
+%deffont "typewriter" xfont "courier-medium-r", vfont "goth", tfont "courbd.ttf", tmfont "wadalab-gothic.ttf"
 %%
 %% Default settings per each line numbers.
 %%
