static LOGFONT lfont;
static int fontflag[FONT_MAXNO];
static enum {
- BOLD_COLOURS, BOLD_SHADOW, BOLD_FONT
-} bold_mode;
+ BOLD_NONE, BOLD_SHADOW, BOLD_FONT
+} bold_font_mode;
+static int bold_colours;
static enum {
UND_LINE, UND_FONT
} und_mode;
static UINT wm_mousewheel = WM_MOUSEWHEEL;
+#define IS_HIGH_VARSEL(wch1, wch2) \
+ ((wch1) == 0xDB40 && ((wch2) >= 0xDD00 && (wch2) <= 0xDDEF))
+#define IS_LOW_VARSEL(wch) \
+ (((wch) >= 0x180B && (wch) <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR */ \
+ ((wch) >= 0xFE00 && (wch) <= 0xFE0F)) /* VARIATION SELECTOR 1-16 */
+
/* Dummy routine, only required in plink. */
void ldisc_update(void *frontend, int echo, int edit)
{
}
/*
+ * Initialise the fonts, simultaneously correcting the guesses
+ * for font_{width,height}.
+ */
+ init_fonts(0,0);
+
+ /*
* Initialise the terminal. (We have to do this _after_
* creating the window, since the terminal is the first thing
* which will call schedule_timer(), which will in turn call
conf_get_int(conf, CONF_savelines));
/*
- * Initialise the fonts, simultaneously correcting the guesses
- * for font_{width,height}.
- */
- init_fonts(0,0);
-
- /*
* Correct the guesses for extra_{width,height}.
*/
{
for (i = 0; i < FONT_MAXNO; i++)
fonts[i] = NULL;
- bold_mode = conf_get_int(conf, CONF_bold_colour) ?
- BOLD_COLOURS : BOLD_FONT;
+ bold_font_mode = conf_get_int(conf, CONF_bold_style) & 1 ?
+ BOLD_FONT : BOLD_NONE;
+ bold_colours = conf_get_int(conf, CONF_bold_style) & 2 ? TRUE : FALSE;
und_mode = UND_FONT;
font = conf_get_fontspec(conf, CONF_font);
}
}
- if (bold_mode == BOLD_FONT) {
+ if (bold_font_mode == BOLD_FONT) {
f(FONT_BOLD, font->charset, fw_bold, FALSE);
}
#undef f
fonts[FONT_UNDERLINE] = 0;
}
- if (bold_mode == BOLD_FONT &&
+ if (bold_font_mode == BOLD_FONT &&
fontsize[FONT_BOLD] != fontsize[FONT_NORMAL]) {
- bold_mode = BOLD_SHADOW;
+ bold_font_mode = BOLD_SHADOW;
DeleteObject(fonts[FONT_BOLD]);
fonts[FONT_BOLD] = 0;
}
{
FontSpec *font = conf_get_fontspec(conf, CONF_font);
FontSpec *prev_font = conf_get_fontspec(prev_conf,
- CONF_font);
+ CONF_font);
if (!strcmp(font->name, prev_font->name) ||
!strcmp(conf_get_str(conf, CONF_line_codepage),
conf_get_int(prev_conf, CONF_font_quality) ||
conf_get_int(conf, CONF_vtmode) !=
conf_get_int(prev_conf, CONF_vtmode) ||
- conf_get_int(conf, CONF_bold_colour) !=
- conf_get_int(prev_conf, CONF_bold_colour) ||
+ conf_get_int(conf, CONF_bold_style) !=
+ conf_get_int(prev_conf, CONF_bold_style) ||
resize_action == RESIZE_DISABLED ||
resize_action == RESIZE_EITHER ||
resize_action != conf_get_int(prev_conf,
h = height / font_height;
if (h < 1) h = 1;
- term_size(term, h, w, conf_get_int(conf, CONF_savelines));
+ if (resizing) {
+ /*
+ * As below, if we're in the middle of an
+ * interactive resize we don't call
+ * back->size. In Windows 7, this case can
+ * arise in maximisation as well via the Aero
+ * snap UI.
+ */
+ need_backend_resize = TRUE;
+ conf_set_int(conf, CONF_height, h);
+ conf_set_int(conf, CONF_width, w);
+ } else {
+ term_size(term, h, w,
+ conf_get_int(conf, CONF_savelines));
+ }
}
reset_window(0);
} else if (wParam == SIZE_RESTORED && was_zoomed) {
* instead we luni_send the characters one by one.
*/
term_seen_key_event(term);
- for (i = 0; i < n; i += 2) {
- if (ldisc)
+ /* don't divide SURROGATE PAIR */
+ if (ldisc) {
+ for (i = 0; i < n; i += 2) {
+ WCHAR hs = *(unsigned short *)(buff+i);
+ if (IS_HIGH_SURROGATE(hs) && i+2 < n) {
+ WCHAR ls = *(unsigned short *)(buff+i+2);
+ if (IS_LOW_SURROGATE(ls)) {
+ luni_send(ldisc, (unsigned short *)(buff+i), 2, 1);
+ i += 2;
+ continue;
+ }
+ }
luni_send(ldisc, (unsigned short *)(buff+i), 1, 1);
+ }
}
free(buff);
}
int text_adjust = 0;
int xoffset = 0;
int maxlen, remaining, opaque;
+ int is_cursor = FALSE;
static int *lpDx = NULL;
static int lpDx_len = 0;
int *lpDx_maybe;
+ int len2; /* for SURROGATE PAIR */
lattr &= LATTR_MODE;
if ((attr & TATTR_ACTCURS) && (cursor_type == 0 || term->big_cursor)) {
attr &= ~(ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS);
- if (bold_mode == BOLD_COLOURS)
- attr &= ~ATTR_BOLD;
-
/* cursor fg and bg */
attr |= (260 << ATTR_FGSHIFT) | (261 << ATTR_BGSHIFT);
+ is_cursor = TRUE;
}
nfont = 0;
if (attr & ATTR_NARROW)
nfont |= FONT_NARROW;
+#ifdef USES_VTLINE_HACK
/* Special hack for the VT100 linedraw glyphs. */
if (text[0] >= 0x23BA && text[0] <= 0x23BD) {
switch ((unsigned char) (text[0])) {
force_manual_underline = 1;
}
}
+#endif
/* Anything left as an original character set is unprintable. */
- if (DIRECT_CHAR(text[0])) {
+ if (DIRECT_CHAR(text[0]) &&
+ (len < 2 || !IS_SURROGATE_PAIR(text[0], text[1]))) {
int i;
for (i = 0; i < len; i++)
text[i] = 0xFFFD;
nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
- if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD))
+ if (bold_font_mode == BOLD_FONT && (attr & ATTR_BOLD))
nfont |= FONT_BOLD;
if (und_mode == UND_FONT && (attr & ATTR_UNDER))
nfont |= FONT_UNDERLINE;
nfg = nbg;
nbg = t;
}
- if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD)) {
+ if (bold_colours && (attr & ATTR_BOLD) && !is_cursor) {
if (nfg < 16) nfg |= 8;
else if (nfg >= 256) nfg |= 1;
}
- if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK)) {
+ if (bold_colours && (attr & ATTR_BLINK)) {
if (nbg < 16) nbg |= 8;
else if (nbg >= 256) nbg |= 1;
}
line_box.top = y;
line_box.right = x + char_width * len;
line_box.bottom = y + font_height;
+ /* adjust line_box.right for SURROGATE PAIR & VARIATION SELECTOR */
+ {
+ int i;
+ int rc_width = 0;
+ for (i = 0; i < len ; i++) {
+ if (i+1 < len && IS_HIGH_VARSEL(text[i], text[i+1])) {
+ i++;
+ } else if (i+1 < len && IS_SURROGATE_PAIR(text[i], text[i+1])) {
+ rc_width += char_width;
+ i++;
+ } else if (IS_LOW_VARSEL(text[i])) {
+ /* do nothing */
+ } else {
+ rc_width += char_width;
+ }
+ }
+ line_box.right = line_box.left + rc_width;
+ }
/* Only want the left half of double width lines */
if (line_box.right > font_width*term->cols+offset_width)
opaque = TRUE; /* start by erasing the rectangle */
for (remaining = len; remaining > 0;
- text += len, remaining -= len, x += char_width * len) {
+ text += len, remaining -= len, x += char_width * len2) {
len = (maxlen < remaining ? maxlen : remaining);
-
- if (len > lpDx_len) {
- if (len > lpDx_len) {
- lpDx_len = len * 9 / 8 + 16;
- lpDx = sresize(lpDx, lpDx_len, int);
- }
+ /* don't divide SURROGATE PAIR and VARIATION SELECTOR */
+ len2 = len;
+ if (maxlen == 1) {
+ if (remaining >= 1 && IS_SURROGATE_PAIR(text[0], text[1]))
+ len++;
+ if (remaining-len >= 1 && IS_LOW_VARSEL(text[len]))
+ len++;
+ else if (remaining-len >= 2 &&
+ IS_HIGH_VARSEL(text[len], text[len+1]))
+ len += 2;
}
+
+ if (len > lpDx_len) {
+ lpDx_len = len * 9 / 8 + 16;
+ lpDx = sresize(lpDx, lpDx_len, int);
+
+ if (lpDx_maybe) lpDx_maybe = lpDx;
+ }
+
{
int i;
- for (i = 0; i < len; i++)
+ /* only last char has dx width in SURROGATE PAIR and
+ * VARIATION sequence */
+ for (i = 0; i < len; i++) {
lpDx[i] = char_width;
+ if (i+1 < len && IS_HIGH_VARSEL(text[i], text[i+1])) {
+ if (i > 0) lpDx[i-1] = 0;
+ lpDx[i] = 0;
+ i++;
+ lpDx[i] = char_width;
+ } else if (i+1 < len && IS_SURROGATE_PAIR(text[i],text[i+1])) {
+ lpDx[i] = 0;
+ i++;
+ lpDx[i] = char_width;
+ } else if (IS_LOW_VARSEL(text[i])) {
+ if (i > 0) lpDx[i-1] = 0;
+ lpDx[i] = char_width;
+ }
+ }
}
/* We're using a private area for direct to font. (512 chars.) */
ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
&line_box, uni_buf, nlen,
lpDx_maybe);
- if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
+ if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
SetBkMode(hdc, TRANSPARENT);
ExtTextOutW(hdc, x + xoffset - 1,
y - font_height * (lattr ==
y - font_height * (lattr == LATTR_BOT) + text_adjust,
ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
&line_box, directbuf, len, lpDx_maybe);
- if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
+ if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
SetBkMode(hdc, TRANSPARENT);
/* GRR: This draws the character outside its box and
opaque && !(attr & TATTR_COMBINING));
/* And the shadow bold hack. */
- if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
+ if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
SetBkMode(hdc, TRANSPARENT);
ExtTextOutW(hdc, x + xoffset - 1,
y - font_height * (lattr ==
{
if (attr & TATTR_COMBINING) {
unsigned long a = 0;
- attr &= ~TATTR_COMBINING;
+ int len0 = 1;
+ /* don't divide SURROGATE PAIR and VARIATION SELECTOR */
+ if (len >= 2 && IS_SURROGATE_PAIR(text[0], text[1]))
+ len0 = 2;
+ if (len-len0 >= 1 && IS_LOW_VARSEL(text[len0])) {
+ attr &= ~TATTR_COMBINING;
+ do_text_internal(ctx, x, y, text, len0+1, attr, lattr);
+ text += len0+1;
+ len -= len0+1;
+ a = TATTR_COMBINING;
+ } else if (len-len0 >= 2 && IS_HIGH_VARSEL(text[len0], text[len0+1])) {
+ attr &= ~TATTR_COMBINING;
+ do_text_internal(ctx, x, y, text, len0+2, attr, lattr);
+ text += len0+2;
+ len -= len0+2;
+ a = TATTR_COMBINING;
+ } else {
+ attr &= ~TATTR_COMBINING;
+ }
+
while (len--) {
- do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
+ if (len >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) {
+ do_text_internal(ctx, x, y, text, 2, attr | a, lattr);
+ len--;
+ text++;
+ } else {
+ do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
+ }
+
text++;
a = TATTR_COMBINING;
}
bgcolour = tmpcolour;
}
- if (bold_mode == BOLD_COLOURS && (attr[i] & ATTR_BOLD)) {
+ if (bold_colours && (attr[i] & ATTR_BOLD)) {
if (fgcolour < 8) /* ANSI colours */
fgcolour += 8;
else if (fgcolour >= 256) /* Default colours */
bgcolour = tmpcolour;
}
- if (bold_mode == BOLD_COLOURS && (attr[tindex] & ATTR_BOLD)) {
+ if (bold_colours && (attr[tindex] & ATTR_BOLD)) {
if (fgcolour < 8) /* ANSI colours */
fgcolour += 8;
else if (fgcolour >= 256) /* Default colours */
/*
* Collect other attributes
*/
- if (bold_mode != BOLD_COLOURS)
+ if (bold_font_mode != BOLD_NONE)
attrBold = attr[tindex] & ATTR_BOLD;
else
attrBold = 0;
bgcolour = -1; /* No coloring */
if (fgcolour >= 256) { /* Default colour */
- if (bold_mode == BOLD_COLOURS && (fgcolour & 1) && bgcolour == -1)
+ if (bold_colours && (fgcolour & 1) && bgcolour == -1)
attrBold = ATTR_BOLD; /* Emphasize text with bold attribute */
fgcolour = -1; /* No coloring */