static XftChar16 *sbuf; static unsigned slen; unsigned n;  if (slen < len) { slen = (len + 1) * 2; sbuf = (XftChar16 *) XtRealloc((char *) sbuf, slen * sizeof(XftChar16)); } for (n = 0; n < len; n++) sbuf[n] = *text++ | (*text2++ << 8); XftDrawString16(screen->renderDraw, getColor(values.foreground), font, x, y, sbuf, len);
xtermXftDrawString(screen->renderDraw, getColor(values.foreground), font, x, y, text, text2, len, FontWidth(screen), NULL);
drawXtermText(TScreen * screen,	      unsigned flags,	      GC gc,	      int x,	      int y,	      int chrset,	      PAIRED_CHARS(Char * text, Char * text2),	      Cardinal len,	      int on_wide){    int real_length = len;    int draw_len;#ifdef XRENDERFONT    if (screen->renderFont) {	Display *dpy = screen->display;	XftFont *font;	XGCValues values;	if (!screen->renderDraw) {	    int scr;	    Drawable draw = VWindow(screen);	    Visual *visual;	    scr = DefaultScreen(dpy);	    visual = DefaultVisual(dpy, scr);	    screen->renderDraw = XftDrawCreate(dpy, draw, visual,					       DefaultColormap(dpy, scr));	}	if ((flags & (BOLD | BLINK)) && screen->renderFontBold)	    font = screen->renderFontBold;	else	    font = screen->renderFont;	XGetGCValues(dpy, gc, GCForeground | GCBackground, &values);	XftDrawRect(screen->renderDraw,		    getColor(values.background),		    x, y,		    len * FontWidth(screen), FontHeight(screen));	y += font->ascent;#if OPT_WIDE_CHARS	if (text2) {	    static XftChar16 *sbuf;	    static unsigned slen;	    unsigned n;	    if (slen < len) {		slen = (len + 1) * 2;		sbuf = (XftChar16 *) XtRealloc((char *) sbuf, slen * sizeof(XftChar16));	    }	    for (n = 0; n < len; n++)		sbuf[n] = *text++ | (*text2++ << 8);	    XftDrawString16(screen->renderDraw,			    getColor(values.foreground),			    font,			    x, y, sbuf, len);	} else#endif	{	    XftDrawString8(screen->renderDraw,			   getColor(values.foreground),			   font,			   x, y, (unsigned char *) text, len);	}	return x + len * FontWidth(screen);    }#endif#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, on_wide);		    x += FontWidth(screen);		}	    } else {		x = drawXtermText(screen, flags, gc2,				  x, y, 0,				  PAIRED_CHARS(text, text2),				  len, on_wide);		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,			      on_wide);	    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, on_wide);	    x += FontWidth(screen);	}	screen->fnt_prop = True;	return x;    }    /* If the font is complete, draw it as-is */    if (screen->fnt_boxes && !screen->force_box_chars) {	TRACE(("drawXtermText%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) {	    int ascent_adjust = 0;	    static XChar2b *sbuf;	    static Cardinal slen;	    Cardinal n;	    int ch = text[0] | (text2[0] << 8);	    int wideness = (on_wide || iswide(ch) != 0)	    && (screen->fnt_dwd != NULL);	    unsigned char *endtext = text + len;	    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;		sbuf[n].byte1 = *text2;		text++;		text2++;		if (wideness) {		    /* filter out those pesky fake characters. */		    while (text < endtext			   && *text == HIDDEN_HI			   && *text2 == HIDDEN_LO) {			text++;			text2++;			len--;		    }		}	    }	    /* This is probably wrong. But it works. */	    draw_len = len;	    if (wideness		&& (screen->fnt_dwd->fid || screen->fnt_dwdb->fid)) {		draw_len = real_length = len * 2;		if ((flags & (BOLD | BLINK)) != 0		    && screen->fnt_dwdb->fid) {		    XSetFont(screen->display, gc, screen->fnt_dwdb->fid);		    ascent_adjust = screen->fnt_dwdb->ascent - screen->fnt_norm->ascent;		} else {		    XSetFont(screen->display, gc, screen->fnt_dwd->fid);		    ascent_adjust = screen->fnt_dwd->ascent - screen->fnt_norm->ascent;		}		/* fix ascent */	    } else if ((flags & (BOLD | BLINK)) != 0		       && screen->fnt_bold->fid)		XSetFont(screen->display, gc, screen->fnt_bold->fid);	    else		XSetFont(screen->display, gc, screen->fnt_norm->fid);	    if (my_wcwidth(ch) == 0)		XDrawString16(screen->display,			      VWindow(screen), gc,			      x, y + ascent_adjust,			      sbuf, n);	    else		XDrawImageString16(screen->display,				   VWindow(screen), gc,				   x, y + ascent_adjust,				   sbuf, n);	} else#endif	{	    XDrawImageString(screen->display, VWindow(screen), gc,			     x, y, (char *) text, len);	    draw_len = 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 + draw_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, on_wide)    } else {			/* fill in missing box-characters */	XFontStruct *font = ((flags & BOLD)			     ? screen->fnt_bold			     : screen->fnt_norm);	Cardinal last, first = 0;	Boolean save_force = screen->force_box_chars;	screen->fnt_boxes = True;	for (last = 0; last < len; last++) {	    unsigned ch = text[last];	    Boolean isMissing;#if OPT_WIDE_CHARS	    if (text2 != 0)		ch |= (text2[last] << 8);	    isMissing = (ch != HIDDEN_CHAR)		&& (xtermMissingChar(ch,				     ((on_wide || iswide(ch)) && screen->fnt_dwd)				     ? screen->fnt_dwd				     : font));#else	    isMissing = xtermMissingChar(ch, font);#endif	    if (isMissing) {		if (last > first) {		    screen->force_box_chars = False;		    DrawSegment(first, last);		    screen->force_box_chars = save_force;		}		xtermDrawBoxChar(screen, ch, flags, gc, DrawX(last), y);		first = last + 1;	    }	}	if (last > first) {	    screen->force_box_chars = False;	    DrawSegment(first, last);	}	screen->fnt_boxes = False;	screen->force_box_chars = save_force;#endif    }    return x + real_length * FontWidth(screen);}