for (i = 0; i < IpDxLEN; i++) IpDx[i] = char_width; }   if (lattr != LATTR_NORM && x*2 >= term->cols) return;  x *= fnt_width; y *= font_height; x += offset_width; y += offset_height;  if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || term->big_cursor)) { attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0); attr ^= ATTR_CUR_XOR; }  nfont = 0; if (cfg.vtmode == VT_POORMAN && lattr != LATTR_NORM) {  lattr = LATTR_WIDE;
void do_text(Context ctx, int x, int y, wchar_t *text, int len,	     unsigned long attr, int lattr){    COLORREF fg, bg, t;    int nfg, nbg, nfont;    HDC hdc = ctx;    RECT line_box;    int force_manual_underline = 0;    int fnt_width, char_width;    int text_adjust = 0;    static int *IpDx = 0, IpDxLEN = 0;    lattr &= LATTR_MODE;    char_width = fnt_width = font_width * (1 + (lattr != LATTR_NORM));    if (attr & ATTR_WIDE)	char_width *= 2;    if (len > IpDxLEN || IpDx[0] != char_width) {	int i;	if (len > IpDxLEN) {	    sfree(IpDx);	    IpDx = snewn(len + 16, int);	    IpDxLEN = (len + 16);	}	for (i = 0; i < IpDxLEN; i++)	    IpDx[i] = char_width;    }    /* Only want the left half of double width lines */    if (lattr != LATTR_NORM && x*2 >= term->cols)	return;    x *= fnt_width;    y *= font_height;    x += offset_width;    y += offset_height;    if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || term->big_cursor)) {	attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0);	attr ^= ATTR_CUR_XOR;    }    nfont = 0;    if (cfg.vtmode == VT_POORMAN && lattr != LATTR_NORM) {	/* Assume a poorman font is borken in other ways too. */	lattr = LATTR_WIDE;    } else	switch (lattr) {	  case LATTR_NORM:	    break;	  case LATTR_WIDE:	    nfont |= FONT_WIDE;	    break;	  default:	    nfont |= FONT_WIDE + FONT_HIGH;	    break;	}    if (attr & ATTR_NARROW)	nfont |= FONT_NARROW;    /* Special hack for the VT100 linedraw glyphs. */    if (text[0] >= 0x23BA && text[0] <= 0x23BD) {	switch ((unsigned char) (text[0])) {	  case 0xBA:	    text_adjust = -2 * font_height / 5;	    break;	  case 0xBB:	    text_adjust = -1 * font_height / 5;	    break;	  case 0xBC:	    text_adjust = font_height / 5;	    break;	  case 0xBD:	    text_adjust = 2 * font_height / 5;	    break;	}	if (lattr == LATTR_TOP || lattr == LATTR_BOT)	    text_adjust *= 2;	text[0] = ucsdata.unitab_xterm['q'];	if (attr & ATTR_UNDER) {	    attr &= ~ATTR_UNDER;	    force_manual_underline = 1;	}    }    /* Anything left as an original character set is unprintable. */    if (DIRECT_CHAR(text[0])) {	int i;	for (i = 0; i < len; i++)	    text[i] = 0xFFFD;    }    /* OEM CP */    if ((text[0] & CSET_MASK) == CSET_OEMCP)	nfont |= FONT_OEM;    nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);    nfg = 2 * (nfg & 0xF) + (nfg & 0x10 ? 1 : 0);    nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);    nbg = 2 * (nbg & 0xF) + (nbg & 0x10 ? 1 : 0);    if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD))	nfont |= FONT_BOLD;    if (und_mode == UND_FONT && (attr & ATTR_UNDER))	nfont |= FONT_UNDERLINE;    another_font(nfont);    if (!fonts[nfont]) {	if (nfont & FONT_UNDERLINE)	    force_manual_underline = 1;	/* Don't do the same for manual bold, it could be bad news. */	nfont &= ~(FONT_BOLD | FONT_UNDERLINE);    }    another_font(nfont);    if (!fonts[nfont])	nfont = FONT_NORMAL;    if (attr & ATTR_REVERSE) {	t = nfg;	nfg = nbg;	nbg = t;    }    if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD))	nfg |= 1;    if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK))	nbg |= 1;    fg = colours[nfg];    bg = colours[nbg];    SelectObject(hdc, fonts[nfont]);    SetTextColor(hdc, fg);    SetBkColor(hdc, bg);    SetBkMode(hdc, OPAQUE);    line_box.left = x;    line_box.top = y;    line_box.right = x + char_width * len;    line_box.bottom = y + font_height;    /* Only want the left half of double width lines */    if (line_box.right > font_width*term->cols+offset_width)	line_box.right = font_width*term->cols+offset_width;    /* We're using a private area for direct to font. (512 chars.) */    if (ucsdata.dbcs_screenfont && (text[0] & CSET_MASK) == CSET_ACP) {	/* Ho Hum, dbcs fonts are a PITA! */	/* To display on W9x I have to convert to UCS */	static wchar_t *uni_buf = 0;	static int uni_len = 0;	int nlen, mptr;	if (len > uni_len) {	    sfree(uni_buf);	    uni_len = len;	    uni_buf = snewn(uni_len, wchar_t);	}	for(nlen = mptr = 0; mptr<len; mptr++) {	    uni_buf[nlen] = 0xFFFD;	    if (IsDBCSLeadByteEx(ucsdata.font_codepage, (BYTE) text[mptr])) {		char dbcstext[2];		dbcstext[0] = text[mptr] & 0xFF;		dbcstext[1] = text[mptr+1] & 0xFF;		IpDx[nlen] += char_width;	        MultiByteToWideChar(ucsdata.font_codepage, MB_USEGLYPHCHARS,				    dbcstext, 2, uni_buf+nlen, 1);		mptr++;	    }	    else	    {		char dbcstext[1];		dbcstext[0] = text[mptr] & 0xFF;	        MultiByteToWideChar(ucsdata.font_codepage, MB_USEGLYPHCHARS,				    dbcstext, 1, uni_buf+nlen, 1);	    }	    nlen++;	}	if (nlen <= 0)	    return;		       /* Eeek! */	ExtTextOutW(hdc, x,		    y - font_height * (lattr == LATTR_BOT) + text_adjust,		    ETO_CLIPPED | ETO_OPAQUE, &line_box, uni_buf, nlen, IpDx);	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {	    SetBkMode(hdc, TRANSPARENT);	    ExtTextOutW(hdc, x - 1,			y - font_height * (lattr ==					   LATTR_BOT) + text_adjust,			ETO_CLIPPED, &line_box, uni_buf, nlen, IpDx);	}	IpDx[0] = -1;    } else if (DIRECT_FONT(text[0])) {	static char *directbuf = NULL;	static int directlen = 0;	int i;	if (len > directlen) {	    directlen = len;	    directbuf = sresize(directbuf, directlen, char);	}	for (i = 0; i < len; i++)	    directbuf[i] = text[i] & 0xFF;	ExtTextOut(hdc, x,		   y - font_height * (lattr == LATTR_BOT) + text_adjust,		   ETO_CLIPPED | ETO_OPAQUE, &line_box, directbuf, len, IpDx);	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {	    SetBkMode(hdc, TRANSPARENT);	    /* GRR: This draws the character outside it's box and can leave	     * 'droppings' even with the clip box! I suppose I could loop it	     * one character at a time ... yuk. 	     * 	     * Or ... I could do a test print with "W", and use +1 or -1 for this	     * shift depending on if the leftmost column is blank...	     */	    ExtTextOut(hdc, x - 1,		       y - font_height * (lattr ==					  LATTR_BOT) + text_adjust,		       ETO_CLIPPED, &line_box, directbuf, len, IpDx);	}    } else {	/* And 'normal' unicode characters */	static WCHAR *wbuf = NULL;	static int wlen = 0;	int i;	if (wlen < len) {	    sfree(wbuf);	    wlen = len;	    wbuf = snewn(wlen, WCHAR);	}	for (i = 0; i < len; i++)	    wbuf[i] = text[i];	/* print Glyphs as they are, without Windows' Shaping*/	exact_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,		      &line_box, wbuf, len, IpDx);/*	ExtTextOutW(hdc, x,		    y - font_height * (lattr == LATTR_BOT) + text_adjust,		    ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx); */	/* And the shadow bold hack. */	if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {	    SetBkMode(hdc, TRANSPARENT);	    ExtTextOutW(hdc, x - 1,			y - font_height * (lattr ==					   LATTR_BOT) + text_adjust,			ETO_CLIPPED, &line_box, wbuf, len, IpDx);	}    }    if (lattr != LATTR_TOP && (force_manual_underline ||			       (und_mode == UND_LINE				&& (attr & ATTR_UNDER)))) {	HPEN oldpen;	int dec = descent;	if (lattr == LATTR_BOT)	    dec = dec * 2 - font_height;	oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, fg));	MoveToEx(hdc, x, y + dec, NULL);	LineTo(hdc, x + len * char_width, y + dec);	oldpen = SelectObject(hdc, oldpen);	DeleteObject(oldpen);    }}