mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-02 12:02:47 -05:00
First-stage support for Unicode combining characters. The `chars'
array of each `termline' structure now contains optional additional entries after the normal number of columns, which are used to chain a linked list of combining characters off any primary termchar that needs it. This means we support arbitrarily many combining characters per cell (unlike xterm's hard limit of 2). Cut and paste works correctly (selecting a character cell containing multiple code points causes all those code points to be cut and pasted). Display works by simply overlaying all the relevant characters on top of one another; this is good enough for Unix (xterm does the same thing), and mostly seems OK for Windows except that the Windows Unicode fonts have a nasty habit of not containing most of the combining characters and thus overlaying an unknown-code-point box on your perfectly good base glyph. I had no idea how to add support in the Mac do_text(), so I've simply stuck in an assertion that will trigger the first time a combining character is displayed, and hopefully this will bite someone with the clue to fix it. [originally from svn r4622]
This commit is contained in:
40
window.c
40
window.c
@ -1136,7 +1136,7 @@ static void init_palette(void)
|
||||
*/
|
||||
static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
|
||||
unsigned short *lpString, UINT cbCount,
|
||||
CONST INT *lpDx)
|
||||
CONST INT *lpDx, int opaque)
|
||||
{
|
||||
|
||||
GCP_RESULTSW gcpr;
|
||||
@ -1152,10 +1152,11 @@ static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
|
||||
gcpr.nGlyphs = cbCount;
|
||||
|
||||
GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
|
||||
FLI_MASK | GCP_CLASSIN);
|
||||
FLI_MASK | GCP_CLASSIN | GCP_DIACRITIC);
|
||||
|
||||
ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
|
||||
buffer, cbCount, lpDx);
|
||||
ExtTextOut(hdc, x, y,
|
||||
ETO_GLYPH_INDEX | ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
|
||||
lprc, buffer, cbCount, lpDx);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2900,8 +2901,8 @@ static void sys_cursor_update(void)
|
||||
*
|
||||
* We are allowed to fiddle with the contents of `text'.
|
||||
*/
|
||||
void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
{
|
||||
COLORREF fg, bg, t;
|
||||
int nfg, nbg, nfont;
|
||||
@ -3031,7 +3032,10 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
SelectObject(hdc, fonts[nfont]);
|
||||
SetTextColor(hdc, fg);
|
||||
SetBkColor(hdc, bg);
|
||||
SetBkMode(hdc, OPAQUE);
|
||||
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;
|
||||
@ -3124,17 +3128,19 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
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);
|
||||
&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);
|
||||
@ -3165,6 +3171,24 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user