зеркало из https://github.com/github/putty.git
Support ESC[38;2;R;G;Bm for 24-bit true colour.
This is a heavily rewritten version of a patch originally by Lorenz Diener; it was tidied up somewhat by Christian Brabandt, and then tidied up more by me. The basic idea is to add to the termchar structure a pair of small structs encoding 24-bit RGB values, each with a flag indicating whether it's turned on; if it is, it overrides any other specification of fg or bg colour for that character cell. I've added a test line to colours.txt containing a few example colours from /usr/share/X11/rgb.txt. In fact it makes quite a good demo to run the whole of rgb.txt through this treatment, with a command such as perl -pe 's!^\s*(\d+)\s+(\d+)\s+(\d+).*$!\e[38;2;$1;$2;$3m$&\e[m!' rgb.txt
This commit is contained in:
Родитель
581dd7071e
Коммит
a4cbd3dfdb
3
LICENCE
3
LICENCE
|
@ -3,7 +3,8 @@ PuTTY is copyright 1997-2017 Simon Tatham.
|
|||
Portions copyright Robert de Bath, Joris van Rantwijk, Delian
|
||||
Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
|
||||
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
|
||||
Kuhn, Colin Watson, Christopher Staite, and CORE SDI S.A.
|
||||
Kuhn, Colin Watson, Christopher Staite, Lorenz Diener, Christian
|
||||
Brabandt, and CORE SDI S.A.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
|
|
|
@ -45,7 +45,7 @@ int from_backend(void *frontend, int is_stderr, const char *data, int len)
|
|||
|
||||
void request_resize(void *frontend, int x, int y) { }
|
||||
void do_text(Context ctx, int x, int y, wchar_t * text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour tc)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -56,7 +56,7 @@ void do_text(Context ctx, int x, int y, wchar_t * text, int len,
|
|||
printf("\n");
|
||||
}
|
||||
void do_cursor(Context ctx, int x, int y, wchar_t * text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour tc)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
28
putty.h
28
putty.h
|
@ -592,12 +592,36 @@ void prompt_ensure_result_size(prompt_t *pr, int len);
|
|||
/* Burn the evidence. (Assumes _all_ strings want free()ing.) */
|
||||
void free_prompts(prompts_t *p);
|
||||
|
||||
/*
|
||||
* Data type definitions for true-colour terminal display.
|
||||
* 'optionalrgb' describes a single RGB colour, which overrides the
|
||||
* other colour settings if 'enabled' is nonzero, and is ignored
|
||||
* otherwise. 'truecolour' contains a pair of those for foreground and
|
||||
* background.
|
||||
*/
|
||||
typedef struct optionalrgb {
|
||||
unsigned char enabled;
|
||||
unsigned char r, g, b;
|
||||
} optionalrgb;
|
||||
extern const optionalrgb optionalrgb_none;
|
||||
typedef struct truecolour {
|
||||
optionalrgb fg, bg;
|
||||
} truecolour;
|
||||
#define optionalrgb_equal(r1,r2) ( \
|
||||
(r1).enabled==(r2).enabled && \
|
||||
(r1).r==(r2).r && (r1).g==(r2).g && (r1).b==(r2).b)
|
||||
#define truecolour_equal(c1,c2) ( \
|
||||
optionalrgb_equal((c1).fg, (c2).fg) && \
|
||||
optionalrgb_equal((c1).bg, (c2).bg))
|
||||
|
||||
/*
|
||||
* Exports from the front end.
|
||||
*/
|
||||
void request_resize(void *frontend, int, int);
|
||||
void do_text(Context, int, int, wchar_t *, int, unsigned long, int);
|
||||
void do_cursor(Context, int, int, wchar_t *, int, unsigned long, int);
|
||||
void do_text(Context, int, int, wchar_t *, int, unsigned long, int,
|
||||
truecolour);
|
||||
void do_cursor(Context, int, int, wchar_t *, int, unsigned long, int,
|
||||
truecolour);
|
||||
int char_width(Context ctx, int uc);
|
||||
#ifdef OPTIMISE_SCROLL
|
||||
void do_scroll(Context, int, int, int);
|
||||
|
|
129
terminal.c
129
terminal.c
|
@ -108,6 +108,7 @@ static void update_sbar(Terminal *);
|
|||
static void deselect(Terminal *);
|
||||
static void term_print_finish(Terminal *);
|
||||
static void scroll(Terminal *, int, int, int, int);
|
||||
static void parse_optionalrgb(optionalrgb *out, unsigned *values);
|
||||
#ifdef OPTIMISE_SCROLL
|
||||
static void scroll_display(Terminal *, int, int, int);
|
||||
#endif /* OPTIMISE_SCROLL */
|
||||
|
@ -283,6 +284,8 @@ static int termchars_equal_override(termchar *a, termchar *b,
|
|||
unsigned long bchr, unsigned long battr)
|
||||
{
|
||||
/* FULL-TERMCHAR */
|
||||
if (!truecolour_equal(a->truecolour, b->truecolour))
|
||||
return FALSE;
|
||||
if (a->chr != bchr)
|
||||
return FALSE;
|
||||
if ((a->attr &~ DATTR_MASK) != (battr &~ DATTR_MASK))
|
||||
|
@ -607,6 +610,24 @@ static void makeliteral_attr(struct buf *b, termchar *c, unsigned long *state)
|
|||
add(b, (unsigned char)(attr & 0xFF));
|
||||
}
|
||||
}
|
||||
static void makeliteral_truecolour(struct buf *b, termchar *c, unsigned long *state)
|
||||
{
|
||||
/*
|
||||
* Put the used parts of the colour info into the buffer.
|
||||
*/
|
||||
add(b, ((c->truecolour.fg.enabled ? 1 : 0) |
|
||||
(c->truecolour.bg.enabled ? 2 : 0)));
|
||||
if (c->truecolour.fg.enabled) {
|
||||
add(b, c->truecolour.fg.r);
|
||||
add(b, c->truecolour.fg.g);
|
||||
add(b, c->truecolour.fg.b);
|
||||
}
|
||||
if (c->truecolour.bg.enabled) {
|
||||
add(b, c->truecolour.bg.r);
|
||||
add(b, c->truecolour.bg.g);
|
||||
add(b, c->truecolour.bg.b);
|
||||
}
|
||||
}
|
||||
static void makeliteral_cc(struct buf *b, termchar *c, unsigned long *state)
|
||||
{
|
||||
/*
|
||||
|
@ -681,6 +702,7 @@ static unsigned char *compressline(termline *ldata)
|
|||
*/
|
||||
makerle(b, ldata, makeliteral_chr);
|
||||
makerle(b, ldata, makeliteral_attr);
|
||||
makerle(b, ldata, makeliteral_truecolour);
|
||||
makerle(b, ldata, makeliteral_cc);
|
||||
|
||||
/*
|
||||
|
@ -826,6 +848,29 @@ static void readliteral_attr(struct buf *b, termchar *c, termline *ldata,
|
|||
|
||||
c->attr = attr;
|
||||
}
|
||||
static void readliteral_truecolour(struct buf *b, termchar *c, termline *ldata,
|
||||
unsigned long *state)
|
||||
{
|
||||
int flags = get(b);
|
||||
|
||||
if (flags & 1) {
|
||||
c->truecolour.fg.enabled = TRUE;
|
||||
c->truecolour.fg.r = get(b);
|
||||
c->truecolour.fg.g = get(b);
|
||||
c->truecolour.fg.b = get(b);
|
||||
} else {
|
||||
c->truecolour.fg = optionalrgb_none;
|
||||
}
|
||||
|
||||
if (flags & 2) {
|
||||
c->truecolour.bg.enabled = TRUE;
|
||||
c->truecolour.bg.r = get(b);
|
||||
c->truecolour.bg.g = get(b);
|
||||
c->truecolour.bg.b = get(b);
|
||||
} else {
|
||||
c->truecolour.bg = optionalrgb_none;
|
||||
}
|
||||
}
|
||||
static void readliteral_cc(struct buf *b, termchar *c, termline *ldata,
|
||||
unsigned long *state)
|
||||
{
|
||||
|
@ -899,6 +944,7 @@ static termline *decompressline(unsigned char *data, int *bytes_used)
|
|||
*/
|
||||
readrle(b, ldata, readliteral_chr);
|
||||
readrle(b, ldata, readliteral_attr);
|
||||
readrle(b, ldata, readliteral_truecolour);
|
||||
readrle(b, ldata, readliteral_cc);
|
||||
|
||||
/* Return the number of bytes read, for diagnostic purposes. */
|
||||
|
@ -1570,6 +1616,8 @@ void term_clrsb(Terminal *term)
|
|||
update_sbar(term);
|
||||
}
|
||||
|
||||
const optionalrgb optionalrgb_none = {0, 0, 0, 0};
|
||||
|
||||
/*
|
||||
* Initialise the terminal.
|
||||
*/
|
||||
|
@ -1646,6 +1694,8 @@ Terminal *term_init(Conf *myconf, struct unicode_data *ucsdata,
|
|||
term->basic_erase_char.chr = CSET_ASCII | ' ';
|
||||
term->basic_erase_char.attr = ATTR_DEFAULT;
|
||||
term->basic_erase_char.cc_next = 0;
|
||||
term->basic_erase_char.truecolour.fg = optionalrgb_none;
|
||||
term->basic_erase_char.truecolour.bg = optionalrgb_none;
|
||||
term->erase_char = term->basic_erase_char;
|
||||
|
||||
return term;
|
||||
|
@ -3212,6 +3262,8 @@ static void term_out(Terminal *term)
|
|||
clear_cc(cline, term->curs.x);
|
||||
cline->chars[term->curs.x].chr = c;
|
||||
cline->chars[term->curs.x].attr = term->curr_attr;
|
||||
cline->chars[term->curs.x].truecolour =
|
||||
term->curr_truecolour;
|
||||
|
||||
term->curs.x++;
|
||||
|
||||
|
@ -3219,6 +3271,8 @@ static void term_out(Terminal *term)
|
|||
clear_cc(cline, term->curs.x);
|
||||
cline->chars[term->curs.x].chr = UCSWIDE;
|
||||
cline->chars[term->curs.x].attr = term->curr_attr;
|
||||
cline->chars[term->curs.x].truecolour =
|
||||
term->curr_truecolour;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
|
@ -3229,6 +3283,8 @@ static void term_out(Terminal *term)
|
|||
clear_cc(cline, term->curs.x);
|
||||
cline->chars[term->curs.x].chr = c;
|
||||
cline->chars[term->curs.x].attr = term->curr_attr;
|
||||
cline->chars[term->curs.x].truecolour =
|
||||
term->curr_truecolour;
|
||||
|
||||
break;
|
||||
case 0:
|
||||
|
@ -3799,6 +3855,8 @@ static void term_out(Terminal *term)
|
|||
switch (def(term->esc_args[i], 0)) {
|
||||
case 0: /* restore defaults */
|
||||
term->curr_attr = term->default_attr;
|
||||
term->curr_truecolour =
|
||||
term->basic_erase_char.truecolour;
|
||||
break;
|
||||
case 1: /* enable bold */
|
||||
compatibility(VT100AVO);
|
||||
|
@ -3860,6 +3918,7 @@ static void term_out(Terminal *term)
|
|||
case 36:
|
||||
case 37:
|
||||
/* foreground */
|
||||
term->curr_truecolour.fg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |=
|
||||
(term->esc_args[i] - 30)<<ATTR_FGSHIFT;
|
||||
|
@ -3873,12 +3932,14 @@ static void term_out(Terminal *term)
|
|||
case 96:
|
||||
case 97:
|
||||
/* aixterm-style bright foreground */
|
||||
term->curr_truecolour.fg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i] - 90 + 8)
|
||||
<< ATTR_FGSHIFT);
|
||||
break;
|
||||
case 39: /* default-foreground */
|
||||
term->curr_truecolour.fg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
term->curr_attr |= ATTR_DEFFG;
|
||||
break;
|
||||
|
@ -3891,6 +3952,7 @@ static void term_out(Terminal *term)
|
|||
case 46:
|
||||
case 47:
|
||||
/* background */
|
||||
term->curr_truecolour.bg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |=
|
||||
(term->esc_args[i] - 40)<<ATTR_BGSHIFT;
|
||||
|
@ -3904,16 +3966,32 @@ static void term_out(Terminal *term)
|
|||
case 106:
|
||||
case 107:
|
||||
/* aixterm-style bright background */
|
||||
term->curr_truecolour.bg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |=
|
||||
((term->esc_args[i] - 100 + 8)
|
||||
<< ATTR_BGSHIFT);
|
||||
break;
|
||||
case 49: /* default-background */
|
||||
term->curr_truecolour.bg.enabled = FALSE;
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
term->curr_attr |= ATTR_DEFBG;
|
||||
break;
|
||||
case 38: /* xterm 256-colour mode */
|
||||
|
||||
/*
|
||||
* 256-colour and true-colour
|
||||
* sequences. A 256-colour
|
||||
* foreground is selected by a
|
||||
* sequence of 3 arguments in the
|
||||
* form 38;5;n, where n is in the
|
||||
* range 0-255. A true-colour RGB
|
||||
* triple is selected by 5 args of
|
||||
* the form 38;2;r;g;b. Replacing
|
||||
* the initial 38 with 48 in both
|
||||
* cases selects the same colour
|
||||
* as the background.
|
||||
*/
|
||||
case 38:
|
||||
if (i+2 < term->esc_nargs &&
|
||||
term->esc_args[i+1] == 5) {
|
||||
term->curr_attr &= ~ATTR_FGMASK;
|
||||
|
@ -3921,9 +3999,16 @@ static void term_out(Terminal *term)
|
|||
((term->esc_args[i+2] & 0xFF)
|
||||
<< ATTR_FGSHIFT);
|
||||
i += 2;
|
||||
}
|
||||
if (i + 4 < term->esc_nargs &&
|
||||
term->esc_args[i + 1] == 2) {
|
||||
parse_optionalrgb(
|
||||
&term->curr_truecolour.fg,
|
||||
term->esc_args + (i+2));
|
||||
i += 4;
|
||||
}
|
||||
break;
|
||||
case 48: /* xterm 256-colour mode */
|
||||
case 48:
|
||||
if (i+2 < term->esc_nargs &&
|
||||
term->esc_args[i+1] == 5) {
|
||||
term->curr_attr &= ~ATTR_BGMASK;
|
||||
|
@ -3932,6 +4017,13 @@ static void term_out(Terminal *term)
|
|||
<< ATTR_BGSHIFT);
|
||||
i += 2;
|
||||
}
|
||||
if (i + 4 < term->esc_nargs &&
|
||||
term->esc_args[i+1] == 2) {
|
||||
parse_optionalrgb(
|
||||
&term->curr_truecolour.bg,
|
||||
term->esc_args + (i+2));
|
||||
i += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4733,6 +4825,19 @@ static void term_out(Terminal *term)
|
|||
logflush(term->logctx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Small subroutine to parse three consecutive escape-sequence
|
||||
* arguments representing a true-colour RGB triple into an
|
||||
* optionalrgb.
|
||||
*/
|
||||
static void parse_optionalrgb(optionalrgb *out, unsigned *values)
|
||||
{
|
||||
out->enabled = TRUE;
|
||||
out->r = values[0] < 256 ? values[0] : 0;
|
||||
out->g = values[1] < 256 ? values[1] : 0;
|
||||
out->b = values[2] < 256 ? values[2] : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* To prevent having to run the reasonably tricky bidi algorithm
|
||||
* too many times, we maintain a cache of the last lineful of data
|
||||
|
@ -5035,6 +5140,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
int last_run_dirty = 0;
|
||||
int laststart, dirtyrect;
|
||||
int *backward;
|
||||
truecolour tc;
|
||||
|
||||
scrpos.y = i + term->disptop;
|
||||
ldata = lineptr(scrpos.y);
|
||||
|
@ -5064,6 +5170,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
tattr = (tattr & ~(ATTR_FGMASK | ATTR_BGMASK)) |
|
||||
ATTR_DEFFG | ATTR_DEFBG;
|
||||
|
||||
tc = d->truecolour;
|
||||
if (!term->xterm_256_colour) {
|
||||
int colour;
|
||||
colour = (tattr & ATTR_FGMASK) >> ATTR_FGSHIFT;
|
||||
|
@ -5131,6 +5238,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
/* FULL-TERMCHAR */
|
||||
newline[j].attr = tattr;
|
||||
newline[j].chr = tchar;
|
||||
newline[j].truecolour = tc;
|
||||
/* Combining characters are still read from lchars */
|
||||
newline[j].cc_next = 0;
|
||||
}
|
||||
|
@ -5181,6 +5289,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
term->disptext[i]->lattr);
|
||||
term->disptext[i]->lattr = ldata->lattr;
|
||||
|
||||
tc = term->erase_char.truecolour;
|
||||
for (j = 0; j < term->cols; j++) {
|
||||
unsigned long tattr, tchar;
|
||||
int break_run, do_copy;
|
||||
|
@ -5194,6 +5303,9 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
|
||||
break_run = ((tattr ^ attr) & term->attr_mask) != 0;
|
||||
|
||||
if (!truecolour_equal(newline[j].truecolour, tc))
|
||||
break_run = TRUE;
|
||||
|
||||
#ifdef USES_VTLINE_HACK
|
||||
/* Special hack for VT100 Linedraw glyphs */
|
||||
if ((tchar >= 0x23BA && tchar <= 0x23BD) ||
|
||||
|
@ -5226,15 +5338,15 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
|
||||
if (break_run) {
|
||||
if ((dirty_run || last_run_dirty) && ccount > 0) {
|
||||
do_text(ctx, start, i, ch, ccount, attr,
|
||||
ldata->lattr);
|
||||
do_text(ctx, start, i, ch, ccount, attr, ldata->lattr, tc);
|
||||
if (attr & (TATTR_ACTCURS | TATTR_PASCURS))
|
||||
do_cursor(ctx, start, i, ch, ccount, attr,
|
||||
ldata->lattr);
|
||||
ldata->lattr, tc);
|
||||
}
|
||||
start = j;
|
||||
ccount = 0;
|
||||
attr = tattr;
|
||||
tc = newline[j].truecolour;
|
||||
cset = CSET_OF(tchar);
|
||||
if (term->ucsdata->dbcs_screenfont)
|
||||
last_run_dirty = dirty_run;
|
||||
|
@ -5303,6 +5415,7 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
copy_termchar(term->disptext[i], j, d);
|
||||
term->disptext[i]->chars[j].chr = tchar;
|
||||
term->disptext[i]->chars[j].attr = tattr;
|
||||
term->disptext[i]->chars[j].truecolour = tc;
|
||||
if (start == j)
|
||||
term->disptext[i]->chars[j].attr |= DATTR_STARTRUN;
|
||||
}
|
||||
|
@ -5324,11 +5437,9 @@ static void do_paint(Terminal *term, Context ctx, int may_optimise)
|
|||
}
|
||||
}
|
||||
if (dirty_run && ccount > 0) {
|
||||
do_text(ctx, start, i, ch, ccount, attr,
|
||||
ldata->lattr);
|
||||
do_text(ctx, start, i, ch, ccount, attr, ldata->lattr, tc);
|
||||
if (attr & (TATTR_ACTCURS | TATTR_PASCURS))
|
||||
do_cursor(ctx, start, i, ch, ccount, attr,
|
||||
ldata->lattr);
|
||||
do_cursor(ctx, start, i, ch, ccount, attr, ldata->lattr, tc);
|
||||
}
|
||||
|
||||
unlineptr(ldata);
|
||||
|
|
|
@ -40,6 +40,7 @@ struct termchar {
|
|||
*/
|
||||
unsigned long chr;
|
||||
unsigned long attr;
|
||||
truecolour truecolour;
|
||||
|
||||
/*
|
||||
* The cc_next field is used to link multiple termchars
|
||||
|
@ -102,6 +103,7 @@ struct terminal_tag {
|
|||
#endif /* OPTIMISE_SCROLL */
|
||||
|
||||
int default_attr, curr_attr, save_attr;
|
||||
truecolour curr_truecolour;
|
||||
termchar basic_erase_char, erase_char;
|
||||
|
||||
bufchain inbuf; /* terminal input buffer */
|
||||
|
|
|
@ -12,3 +12,4 @@ xterm 256: [48;5;16mg[48;5;232mr[48;5;233me[48;5;234my[48;5;235ms[48;5;236
|
|||
[38;5;160ma0[38;5;161ma1[38;5;162ma2[38;5;163ma3[38;5;164ma4[38;5;165ma5[38;5;166ma6[38;5;167ma7 [38;5;168ma8[38;5;169ma9[38;5;170maa[38;5;171mab[38;5;172mac[38;5;173mad[38;5;174mae[38;5;175maf [38;5;176mb0[38;5;177mb1[38;5;178mb2[38;5;179mb3[38;5;180mb4[38;5;181mb5[38;5;182mb6[38;5;183mb7 [38;5;184mb8[38;5;185mb9[38;5;186mba[38;5;187mbb[38;5;188mbc[38;5;189mbd[38;5;190mbe[38;5;191mbf[m
|
||||
[38;5;192mc0[38;5;193mc1[38;5;194mc2[38;5;195mc3[38;5;196mc4[38;5;197mc5[38;5;198mc6[38;5;199mc7 [38;5;200mc8[38;5;201mc9[38;5;202mca[38;5;203mcb[38;5;204mcc[38;5;205mcd[38;5;206mce[38;5;207mcf [38;5;208md0[38;5;209md1[38;5;210md2[38;5;211md3[38;5;212md4[38;5;213md5[38;5;214md6[38;5;215md7 [38;5;216md8[38;5;217md9[38;5;218mda[38;5;219mdb[38;5;220mdc[38;5;221mdd[38;5;222mde[38;5;223mdf[m
|
||||
[38;5;224me0[38;5;225me1[38;5;226me2[38;5;227me3[38;5;228me4[38;5;229me5[38;5;230me6[38;5;231me7 [38;5;232me8[38;5;233me9[38;5;234mea[38;5;235meb[38;5;236mec[38;5;237med[38;5;238mee[38;5;239mef [38;5;240mf0[38;5;241mf1[38;5;242mf2[38;5;243mf3[38;5;244mf4[38;5;245mf5[38;5;246mf6[38;5;247mf7 [38;5;248mf8[38;5;249mf9[38;5;250mfa[38;5;251mfb[38;5;252mfc[38;5;253mfd[38;5;254mfe[38;5;255mff[m
|
||||
24-bit colour: [38;2;112;128;144mSlateGrey[m [38;2;107;142;35mOliveDrab[m [38;2;218;165;32mgoldenrod[m [38;2;139;69;19mSaddleBrown[m [30;48;2;148;0;211mDarkViolet (bg)[m
|
||||
|
|
|
@ -3029,6 +3029,24 @@ static void draw_set_colour(struct draw_ctx *dctx, int col)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void draw_set_colour_rgb(struct draw_ctx *dctx, optionalrgb orgb)
|
||||
{
|
||||
#ifdef DRAW_TEXT_GDK
|
||||
if (dctx->uctx.type == DRAWTYPE_GDK) {
|
||||
GdkColor color;
|
||||
color.red = orgb.r * 256;
|
||||
color.green = orgb.g * 256;
|
||||
color.blue = orgb.b * 256;
|
||||
gdk_gc_set_rgb_fg_color(dctx->uctx.u.gdk.gc, &color);
|
||||
}
|
||||
#endif
|
||||
#ifdef DRAW_TEXT_CAIRO
|
||||
if (dctx->uctx.type == DRAWTYPE_CAIRO)
|
||||
cairo_set_source_rgb(dctx->uctx.u.cairo.cr,
|
||||
orgb.r / 255.0, orgb.g / 255.0, orgb.b / 255.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void draw_rectangle(struct draw_ctx *dctx, int filled,
|
||||
int x, int y, int w, int h)
|
||||
{
|
||||
|
@ -3222,7 +3240,7 @@ static void draw_backing_rect(struct gui_data *inst)
|
|||
* We are allowed to fiddle with the contents of `text'.
|
||||
*/
|
||||
void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
struct draw_ctx *dctx = (struct draw_ctx *)ctx;
|
||||
struct gui_data *inst = dctx->inst;
|
||||
|
@ -3316,13 +3334,19 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
((lattr & LATTR_MODE) == LATTR_BOT));
|
||||
}
|
||||
|
||||
draw_set_colour(dctx, nbg);
|
||||
if (truecolour.bg.enabled)
|
||||
draw_set_colour_rgb(dctx, truecolour.bg);
|
||||
else
|
||||
draw_set_colour(dctx, nbg);
|
||||
draw_rectangle(dctx, TRUE,
|
||||
x*inst->font_width+inst->window_border,
|
||||
y*inst->font_height+inst->window_border,
|
||||
rlen*widefactor*inst->font_width, inst->font_height);
|
||||
|
||||
draw_set_colour(dctx, nfg);
|
||||
if (truecolour.fg.enabled)
|
||||
draw_set_colour_rgb(dctx, truecolour.fg);
|
||||
else
|
||||
draw_set_colour(dctx, nfg);
|
||||
if (ncombining > 1) {
|
||||
assert(len == 1);
|
||||
unifont_draw_combining(&dctx->uctx, inst->fonts[fontid],
|
||||
|
@ -3362,13 +3386,13 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
}
|
||||
|
||||
void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
struct draw_ctx *dctx = (struct draw_ctx *)ctx;
|
||||
struct gui_data *inst = dctx->inst;
|
||||
int widefactor;
|
||||
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr);
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr, truecolour);
|
||||
|
||||
if (attr & ATTR_WIDE) {
|
||||
widefactor = 2;
|
||||
|
@ -3392,7 +3416,7 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
}
|
||||
|
||||
void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
struct draw_ctx *dctx = (struct draw_ctx *)ctx;
|
||||
struct gui_data *inst = dctx->inst;
|
||||
|
@ -3409,7 +3433,7 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
active = 1;
|
||||
} else
|
||||
active = 0;
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr);
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr, truecolour);
|
||||
|
||||
if (attr & TATTR_COMBINING)
|
||||
len = 1;
|
||||
|
|
|
@ -3395,7 +3395,7 @@ static void sys_cursor_update(void)
|
|||
* We are allowed to fiddle with the contents of `text'.
|
||||
*/
|
||||
void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
COLORREF fg, bg, t;
|
||||
int nfg, nbg, nfont;
|
||||
|
@ -3522,8 +3522,16 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
if (nbg < 16) nbg |= 8;
|
||||
else if (nbg >= 256) nbg |= 1;
|
||||
}
|
||||
fg = colours[nfg];
|
||||
bg = colours[nbg];
|
||||
if (truecolour.fg.enabled)
|
||||
fg = RGB(truecolour.fg.r, truecolour.fg.g, truecolour.fg.b);
|
||||
else
|
||||
fg = colours[nfg];
|
||||
|
||||
if (truecolour.bg.enabled)
|
||||
bg = RGB(truecolour.bg.r, truecolour.bg.g, truecolour.bg.b);
|
||||
else
|
||||
bg = colours[nbg];
|
||||
|
||||
SelectObject(hdc, fonts[nfont]);
|
||||
SetTextColor(hdc, fg);
|
||||
SetBkColor(hdc, bg);
|
||||
|
@ -3768,7 +3776,7 @@ void do_text_internal(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)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
if (attr & TATTR_COMBINING) {
|
||||
unsigned long a = 0;
|
||||
|
@ -3778,13 +3786,13 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
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);
|
||||
do_text_internal(ctx, x, y, text, len0+1, attr, lattr, truecolour);
|
||||
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);
|
||||
do_text_internal(ctx, x, y, text, len0+2, attr, lattr, truecolour);
|
||||
text += len0+2;
|
||||
len -= len0+2;
|
||||
a = TATTR_COMBINING;
|
||||
|
@ -3794,22 +3802,21 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
|
||||
while (len--) {
|
||||
if (len >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) {
|
||||
do_text_internal(ctx, x, y, text, 2, attr | a, lattr);
|
||||
do_text_internal(ctx, x, y, text, 2, attr | a, lattr, truecolour);
|
||||
len--;
|
||||
text++;
|
||||
} else {
|
||||
do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
|
||||
}
|
||||
} else
|
||||
do_text_internal(ctx, x, y, text, 1, attr | a, lattr, truecolour);
|
||||
|
||||
text++;
|
||||
a = TATTR_COMBINING;
|
||||
}
|
||||
} else
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr);
|
||||
do_text_internal(ctx, x, y, text, len, attr, lattr, truecolour);
|
||||
}
|
||||
|
||||
void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
||||
unsigned long attr, int lattr)
|
||||
unsigned long attr, int lattr, truecolour truecolour)
|
||||
{
|
||||
|
||||
int fnt_width;
|
||||
|
@ -3821,7 +3828,7 @@ void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
|
|||
|
||||
if ((attr & TATTR_ACTCURS) && (ctype == 0 || term->big_cursor)) {
|
||||
if (*text != UCSWIDE) {
|
||||
do_text(ctx, x, y, text, len, attr, lattr);
|
||||
do_text(ctx, x, y, text, len, attr, lattr, truecolour);
|
||||
return;
|
||||
}
|
||||
ctype = 2;
|
||||
|
|
Загрузка…
Ссылка в новой задаче