From 438c980cf11d990c68339743fe03c66116672339 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 12 Feb 2021 17:35:48 +0000 Subject: [PATCH] Move CSET_OEMCP and CSET_ACP into Unicode surrogate space. Each of these #defines represents a block of 256 code values that are used, internally to the terminal code, to indicate that a character is in one of the currently selected single-byte character sets. One effect of this is that reconfiguring the character set in mid-session causes all the text already on screen to be redrawn. Unfortunately, those 512 code points were allocated at 0xF000-0xF1FF, which is inside the Unicode private-use area. So if a font uses that area to define actually useful glyphs, then those glyphs won't be displayed correctly by PuTTY; instead, outputting 0xF000+'A' (for example) will display as 'A'. A user recently reported this problem with the 'Hack' font from https://github.com/ryanoasis/nerd-fonts . RDB's comment next to the #defines suggested that this was done on purpose for consistency with Linux (though it's not clear what part of Linux; perhaps the virtual console driver used to work this way?). But now it's getting in the way of actually useful Unicode characters, that consistency doesn't seem like the most important thing. (Also, it just seems wrong to me that you even _can_ cause PuTTY's terminal emulator to use these special internal character representations by sending legal UTF-8.) So I've moved this block of 512 characters to 0xDC00, which is in the Unicode surrogate space, and hence can't be stored in the terminal by sending UTF-8 at all (since our UTF-8 decoder rejects that range, as per spec). That's where we were already keeping other magic blocks like CSET_LINEDRW and CSET_SCOACS, and there's still room for two more. The net effect should be that in Windows PuTTY, U+F000 to U+F1FF are now displayed as whatever your font wants to show. --- putty.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/putty.h b/putty.h index 1200b4da..db308427 100644 --- a/putty.h +++ b/putty.h @@ -216,9 +216,9 @@ extern const int colour_indices_oscp_to_osc4[OSCP_NCOLOURS]; #define ATTR_INVALID 0x03FFFFU -/* Like Linux use the F000 page for direct to font. */ -#define CSET_OEMCP 0x0000F000UL /* OEM Codepage DTF */ -#define CSET_ACP 0x0000F100UL /* Ansi Codepage DTF */ +/* Use the DC00 page for direct to font. */ +#define CSET_OEMCP 0x0000DC00UL /* OEM Codepage DTF */ +#define CSET_ACP 0x0000DD00UL /* Ansi Codepage DTF */ /* These are internal use overlapping with the UTF-16 surrogates */ #define CSET_ASCII 0x0000D800UL /* normal ASCII charset ESC ( B */ @@ -228,7 +228,7 @@ extern const int colour_indices_oscp_to_osc4[OSCP_NCOLOURS]; #define CSET_MASK 0xFFFFFF00UL /* Character set mask */ #define DIRECT_CHAR(c) ((c&0xFFFFFC00)==0xD800) -#define DIRECT_FONT(c) ((c&0xFFFFFE00)==0xF000) +#define DIRECT_FONT(c) ((c&0xFFFFFE00)==0xDC00) #define UCSERR (CSET_LINEDRW|'a') /* UCS Format error character. */ /*