screen->force_box_chars = save_force;
drawXtermText(	register TScreen *screen,	unsigned flags,	GC gc,	int x,	int y,	int chrset,	PAIRED_CHARS(Char *text, Char *text2),	Cardinal len){#if OPT_WIDE_CHARS	/*	 * It's simpler to pass in a null pointer for text2 in places where	 * we only use codes through 255.  Fix text2 here so we can increment	 * it, etc.	 */	if (text2 == 0) {		static Char *dbuf;		static unsigned dlen;		if (dlen <= len) {			dlen = (len + 1) * 2;			dbuf = (Char *)XtRealloc((char *)dbuf, dlen);			memset(dbuf, 0, dlen);		}		text2 = dbuf;	}#endif#if OPT_DEC_CHRSET	if (CSET_DOUBLE(chrset)) {		/* We could try drawing double-size characters in the icon, but		 * given that the icon font is usually nil or nil2, there		 * doesn't seem to be much point.		 */		GC gc2 = (!IsIcon(screen) && screen->font_doublesize)			? xterm_DoubleGC(chrset, flags, gc)			: 0;		TRACE(("DRAWTEXT%c[%4d,%4d] (%d) %d:%.*s\n",			screen->cursor_state == OFF ? ' ' : '*',			y, x, chrset, len, (int)len, text));		if (gc2 != 0) {	/* draw actual double-sized characters */			XFontStruct *fs = screen->double_fonts[xterm_Double_index(chrset, flags)].fs;			XRectangle rect, *rp = &rect;			Cardinal nr = 1;			int adjust;			SAVE_FONT_INFO (screen);			screen->fnt_wide *= 2;			rect.x = 0;			rect.y = 0;			rect.width = len * screen->fnt_wide;			rect.height = FontHeight(screen);			switch (chrset) {			case CSET_DHL_TOP:				rect.y = - (rect.height / 2);				y -= rect.y;				screen->fnt_high *= 2;				break;			case CSET_DHL_BOT:				rect.y = (rect.height / 2);				y -= rect.y;				screen->fnt_high *= 2;				break;			default:				nr = 0;				break;			}			/*			 * Though it is the right "size", a given bold font may			 * be shifted up by a pixel or two.  Shift it back into			 * the clipping rectangle.			 */			if (nr != 0) {				adjust = fs->ascent					+ fs->descent					- (2 * FontHeight(screen));				rect.y -= adjust;				y += adjust;			}			if (nr)				XSetClipRectangles(screen->display, gc2,					x, y, rp, nr, YXBanded);			else				XSetClipMask(screen->display, gc2, None);			/*			 * If we're trying to use proportional font, or if the			 * font server didn't give us what we asked for wrt			 * width, position each character independently.			 */			if (screen->fnt_prop			 || (fs->min_bounds.width != fs->max_bounds.width)			 || (fs->min_bounds.width != 2 * FontWidth(screen)))			{				while (len--) {					x = drawXtermText(screen, flags, gc2,						x, y, 0,						PAIRED_CHARS(text++, text2++),						1);					x += FontWidth(screen);				}			} else {				x = drawXtermText(screen, flags, gc2,					x, y, 0,					PAIRED_CHARS(text, text2),					len);				x += len * FontWidth(screen);			}			TRACE(("drewtext [%4d,%4d]\n", y, x));			SAVE_FONT_INFO (screen);		} else {	/* simulate double-sized characters */#if OPT_WIDE_CHARS			Char *wide = 0;#endif			unsigned need = 2 * len;			Char *temp = (Char *) malloc(need);			int n = 0;			if_OPT_WIDE_CHARS(screen,{				wide = (Char *)malloc(need);			})			while (len--) {				if_OPT_WIDE_CHARS(screen,{					wide[n] = *text2++;					wide[n+1] = 0;				})				temp[n++] = *text++;				temp[n++] = ' ';			}			x = drawXtermText(screen, flags, gc, x, y, 0, PAIRED_CHARS(temp, wide), n);			free(temp);			if_OPT_WIDE_CHARS(screen,{				free(wide);			})		}		return x;	}#endif	/*	 * If we're asked to display a proportional font, do this with a fixed	 * pitch.  Yes, it's ugly.  But we cannot distinguish the use of xterm	 * as a dumb terminal vs its use as in fullscreen programs such as vi.	 */	if (screen->fnt_prop) {		int	adj, width;		GC	fillGC = gc;	/* might be cursorGC */		XFontStruct *fs = (flags & (BOLD|BLINK))				? screen->fnt_bold				: screen->fnt_norm;		screen->fnt_prop = False;#define GC_PAIRS(a,b) \	if (gc == a) fillGC = b; \	if (gc == b) fillGC = a		/*		 * Fill the area where we'll write the characters, otherwise		 * we'll get gaps between them.  The cursor is a special case,		 * because the XFillRectangle call only uses the foreground,		 * while we've set the cursor color in the background.  So we		 * need a special GC for that.		 */		if (gc == screen->cursorGC		 || gc == screen->reversecursorGC)			fillGC = screen->fillCursorGC;		GC_PAIRS(NormalGC(screen),      ReverseGC(screen));		GC_PAIRS(NormalBoldGC(screen),  ReverseBoldGC(screen));		XFillRectangle (screen->display, VWindow(screen), fillGC,			x, y, len * FontWidth(screen), FontHeight(screen));		while (len--) {			width = XTextWidth(fs, (char *)text, 1);			adj = (FontWidth(screen) - width) / 2;			(void)drawXtermText(screen, flags, gc, x + adj, y,					    chrset,					    PAIRED_CHARS(text++, text2++), 1);			x += FontWidth(screen);		}		screen->fnt_prop = True;		return x;	}	/* If the font is complete, draw it as-is */	if (screen->fnt_boxes) {		TRACE(("drawtext%c[%4d,%4d] (%d) %d:%s\n",			screen->cursor_state == OFF ? ' ' : '*',			y, x, chrset, len,			visibleChars(PAIRED_CHARS(text, text2), len)));		y += FontAscent(screen);#if OPT_WIDE_CHARS		if (screen->wide_chars) {			static XChar2b *sbuf;			static Cardinal slen;			Cardinal n;			if (slen < len) {				slen = (len + 1) * 2;				sbuf = (XChar2b *)XtRealloc((char *)sbuf, slen * sizeof(*sbuf));			}			for (n = 0; n < len; n++) {				sbuf[n].byte2 = text[n];				sbuf[n].byte1 = text2[n];			}			XDrawImageString16(screen->display, VWindow(screen), gc,				x, y, sbuf, len);		} else#endif		{		XDrawImageString(screen->display, VWindow(screen), gc,			x, y,  (char *)text, len);		if ((flags & (BOLD|BLINK)) && screen->enbolden) {#if OPT_CLIP_BOLD			/*			 * This special case is a couple of percent slower, but			 * avoids a lot of pixel trash in rxcurses' hanoi.cmd			 * demo (e.g., 10x20 font).			 */			if (screen->fnt_wide > 2) {				XRectangle clip;				int clip_x = x;				int clip_y = y - FontHeight(screen) + FontDescent(screen);				clip.x = 0;				clip.y = 0;				clip.height = FontHeight(screen);				clip.width = screen->fnt_wide * len;				XSetClipRectangles(screen->display, gc,					clip_x, clip_y,					&clip, 1, Unsorted);			}#endif			XDrawString(screen->display, VWindow(screen), gc,				x + 1, y, (char *)text, len);#if OPT_CLIP_BOLD			XSetClipMask(screen->display, gc, None);#endif		}		}		if ((flags & UNDERLINE) && screen->underline) {			if (FontDescent(screen) > 1)				y++;			XDrawLine(screen->display, VWindow(screen), gc,				x, y, x + len * screen->fnt_wide - 1, y);		}#if OPT_BOX_CHARS#define DrawX(col) x + (col * (screen->fnt_wide))#define DrawSegment(first,last) (void)drawXtermText(screen, flags, gc, DrawX(first), y, chrset, PAIRED_CHARS(text+first, text2+first), last-first)	} else {	/* fill in missing box-characters */		XFontStruct *font = (flags & BOLD)				  ? screen->fnt_bold				  : screen->fnt_norm;		Cardinal last, first = 0;		screen->fnt_boxes = True;		for (last = 0; last < len; last++) {			unsigned ch = text[last];#if OPT_WIDE_CHARS			if (text2 != 0)				ch |= (text2[last] << 8);#endif			if (xtermMissingChar(ch, font)) {				if (last > first) {					DrawSegment(first,last);				}				xtermDrawBoxChar(screen, ch, flags, gc, DrawX(last), y);				first = last + 1;			}		}		if (last > first) {			DrawSegment(first,last);		}		screen->fnt_boxes = False;#endif	}	return x + len * FontWidth(screen);}