- 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+fnt_width*len;
- line_box.bottom = y+font_height;
- ExtTextOut (hdc, x, y, ETO_CLIPPED|ETO_OPAQUE, &line_box, text, 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, ETO_CLIPPED, &line_box, text, len, IpDx);
- }
- if (force_manual_underline ||
- (und_mode == UND_LINE && (attr & ATTR_UNDER))) {
- HPEN oldpen;
- oldpen = SelectObject (hdc, CreatePen(PS_SOLID, 0, fg));
- MoveToEx (hdc, x, y+descent, NULL);
- LineTo (hdc, x+len*fnt_width, y+descent);
- oldpen = SelectObject (hdc, oldpen);
- DeleteObject (oldpen);
- }
- if ((attr & ATTR_PASCURS) && cfg.cursor_type == 0) {
+ SelectObject(hdc, fonts[nfont]);
+ SetTextColor(hdc, fg);
+ SetBkColor(hdc, bg);
+ if (attr & TATTR_COMBINING)
+ SetBkMode(hdc, TRANSPARENT);
+ else
+ 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, !(attr & TATTR_COMBINING));
+/* 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);
+ }
+}
+
+/*
+ * Wrapper that handles combining characters.
+ */
+void do_text(Context ctx, int x, int y, wchar_t *text, int len,
+ unsigned long attr, int lattr)
+{
+ if (attr & TATTR_COMBINING) {
+ unsigned long a = 0;
+ attr &= ~TATTR_COMBINING;
+ while (len--) {
+ do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
+ text++;
+ a = TATTR_COMBINING;
+ }
+ } else
+ do_text_internal(ctx, x, y, text, len, attr, lattr);
+}
+
+void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
+ unsigned long attr, int lattr)
+{
+
+ int fnt_width;
+ int char_width;
+ HDC hdc = ctx;
+ int ctype = cfg.cursor_type;
+
+ if ((attr & TATTR_ACTCURS) && (ctype == 0 || term->big_cursor)) {
+ if (*text != UCSWIDE) {
+ do_text(ctx, x, y, text, len, attr, lattr);
+ return;
+ }
+ ctype = 2;
+ attr |= TATTR_RIGHTCURS;
+ }
+
+ fnt_width = char_width = font_width * (1 + (lattr != LATTR_NORM));
+ if (attr & ATTR_WIDE)
+ char_width *= 2;
+ x *= fnt_width;
+ y *= font_height;
+ x += offset_width;
+ y += offset_height;
+
+ if ((attr & TATTR_PASCURS) && (ctype == 0 || term->big_cursor)) {