1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Preserve more attributes of text copied as RTF. Thanks to Stephen Balousek.

[originally from svn r6555]
This commit is contained in:
Owen Dunn 2006-02-13 22:18:17 +00:00
parent 4475ed6ed9
commit d526e3bb33
6 changed files with 181 additions and 12 deletions

View File

@ -595,7 +595,7 @@ static void text_click(Session *s, EventRecord *event)
lastwhen = TickCount();
}
void write_clip(void *cookie, wchar_t *data, int len, int must_deselect)
void write_clip(void *cookie, wchar_t *data, int *attr, int len, int must_deselect)
{
#if !TARGET_API_MAC_CARBON
Session *s = cookie;

View File

@ -1176,7 +1176,7 @@ void get_clip(void *frontend, wchar_t ** p, int *len)
/* FIXME */
}
void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
void write_clip(void *frontend, wchar_t *data, int *arttr, int len, int must_deselect)
{
//SessionWindow *win = (SessionWindow *)frontend;
/* FIXME */

View File

@ -680,7 +680,7 @@ void free_ctx(Context);
void palette_set(void *frontend, int, int, int, int);
void palette_reset(void *frontend);
void write_aclip(void *frontend, char *, int, int);
void write_clip(void *frontend, wchar_t *, int, int);
void write_clip(void *frontend, wchar_t *, int *, int, int);
void get_clip(void *frontend, wchar_t **, int *);
void optimised_move(void *frontend, int, int, int);
void set_raw_mouse_mode(void *frontend, int);

View File

@ -5047,10 +5047,15 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
int old_top_x;
int wblen = 0; /* workbuf len */
int buflen; /* amount of memory allocated to workbuf */
int *attrbuf; /* Attribute buffer */
int *attrptr;
int attr;
buflen = 5120; /* Default size */
workbuf = snewn(buflen, wchar_t);
attrbuf = buflen ? snewn(buflen, int) : 0;
wbptr = workbuf; /* start filling here */
attrptr = attrbuf;
old_top_x = top.x; /* needed for rect==1 */
while (poslt(top, bottom)) {
@ -5113,6 +5118,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
while (1) {
int uc = ldata->chars[x].chr;
attr = ldata->chars[x].attr;
switch (uc & CSET_MASK) {
case CSET_LINEDRW:
@ -5170,9 +5176,12 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
buflen += 100;
workbuf = sresize(workbuf, buflen, wchar_t);
wbptr = workbuf + wblen;
attrbuf = sresize(attrbuf, buflen, int);
attrptr = attrbuf + wblen;
}
wblen++;
*wbptr++ = *p;
*attrptr++ = attr;
}
if (ldata->chars[x].cc_next)
@ -5187,6 +5196,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
for (i = 0; i < sel_nl_sz; i++) {
wblen++;
*wbptr++ = sel_nl[i];
*attrptr++ = 0;
}
}
top.y++;
@ -5198,7 +5208,7 @@ static void clipme(Terminal *term, pos top, pos bottom, int rect, int desel)
wblen++;
*wbptr++ = 0;
#endif
write_clip(term->frontend, workbuf, wblen, desel); /* transfer to clipbd */
write_clip(term->frontend, workbuf, attrbuf, wblen, desel); /* transfer to clipbd */
if (buflen > 0) /* indicates we allocated this buffer */
sfree(workbuf);
}

View File

@ -1491,7 +1491,7 @@ char * retrieve_cutbuffer(int * nbytes)
return ptr;
}
void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_deselect)
{
struct gui_data *inst = (struct gui_data *)frontend;
if (inst->pasteout_data)

View File

@ -4462,7 +4462,7 @@ void write_aclip(void *frontend, char *data, int len, int must_deselect)
/*
* Note: unlike write_aclip() this will not append a nul.
*/
void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_deselect)
{
HGLOBAL clipdata, clipdata2, clipdata3;
int len2;
@ -4498,14 +4498,83 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
int rtfsize = 0;
int multilen, blen, alen, totallen, i;
char before[16], after[4];
int fgcolour, lastfgcolour = 0;
int bgcolour, lastbgcolour = 0;
int attrBold, lastAttrBold = 0;
int attrUnder, lastAttrUnder = 0;
int palette[NALLCOLOURS];
int numcolours;
get_unitab(CP_ACP, unitab, 0);
rtfsize = 100 + strlen(cfg.font.name);
rtf = snewn(rtfsize, char);
sprintf(rtf, "{\\rtf1\\ansi%d{\\fonttbl\\f0\\fmodern %s;}\\f0 ",
GetACP(), cfg.font.name);
rtflen = strlen(rtf);
rtflen = sprintf(rtf, "{\\rtf1\\ansi\\deff0{\\fonttbl\\f0\\fmodern %s;}\\f0\\fs%d",
cfg.font.name, cfg.font.height*2);
/*
* Add colour palette
* {\colortbl ;\red255\green0\blue0;\red0\green0\blue128;}
*/
/*
* First - Determine all colours in use
* o Foregound and background colours share the same palette
*/
if (attr) {
memset(palette, 0, sizeof(palette));
for (i = 0; i < (len-1); i++) {
fgcolour = ((attr[i] & ATTR_FGMASK) >> ATTR_FGSHIFT);
bgcolour = ((attr[i] & ATTR_BGMASK) >> ATTR_BGSHIFT);
if (attr[i] & ATTR_REVERSE) {
int tmpcolour = fgcolour; /* Swap foreground and background */
fgcolour = bgcolour;
bgcolour = tmpcolour;
}
if (bold_mode == BOLD_COLOURS && (attr[i] & ATTR_BOLD)) {
if (fgcolour < 8) /* ANSI colours */
fgcolour += 8;
else if (fgcolour >= 256) /* Default colours */
fgcolour ++;
}
if (attr[i] & ATTR_BLINK) {
if (bgcolour < 8) /* ANSI colours */
bgcolour += 8;
else if (bgcolour >= 256) /* Default colours */
bgcolour ++;
}
palette[fgcolour]++;
palette[bgcolour]++;
}
/*
* Next - Create a reduced palette
*/
numcolours = 0;
for (i = 0; i < NALLCOLOURS; i++) {
if (palette[i] != 0)
palette[i] = ++numcolours;
}
/*
* Finally - Write the colour table
*/
rtf = sresize(rtf, rtfsize + (numcolours * 25), char);
strcat(rtf, "{\\colortbl ;");
rtflen = strlen(rtf);
for (i = 0; i < NALLCOLOURS; i++) {
if (palette[i] != 0) {
rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;", defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue);
}
}
strcpy(&rtf[rtflen], "}");
rtflen ++;
}
/*
* We want to construct a piece of RTF that specifies the
@ -4532,7 +4601,96 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
tdata[tindex+1] == '\n') {
tindex++;
uindex++;
}
/*
* Set text attributes
*/
if (attr) {
if (rtfsize < rtflen + 64) {
rtfsize = rtflen + 512;
rtf = sresize(rtf, rtfsize, char);
}
/*
* Determine foreground and background colours
*/
fgcolour = ((attr[tindex] & ATTR_FGMASK) >> ATTR_FGSHIFT);
bgcolour = ((attr[tindex] & ATTR_BGMASK) >> ATTR_BGSHIFT);
if (attr[tindex] & ATTR_REVERSE) {
int tmpcolour = fgcolour; /* Swap foreground and background */
fgcolour = bgcolour;
bgcolour = tmpcolour;
}
if (bold_mode == BOLD_COLOURS && (attr[tindex] & ATTR_BOLD)) {
if (fgcolour < 8) /* ANSI colours */
fgcolour += 8;
else if (fgcolour >= 256) /* Default colours */
fgcolour ++;
}
if (attr[tindex] & ATTR_BLINK) {
if (bgcolour < 8) /* ANSI colours */
bgcolour += 8;
else if (bgcolour >= 256) /* Default colours */
bgcolour ++;
}
/*
* Collect other attributes
*/
if (bold_mode != BOLD_COLOURS)
attrBold = attr[tindex] & ATTR_BOLD;
else
attrBold = 0;
attrUnder = attr[tindex] & ATTR_UNDER;
/*
* Reverse video
* o If video isn't reversed, ignore colour attributes for default foregound
* or background.
* o Special case where bolded text is displayed using the default foregound
* and background colours - force to bolded RTF.
*/
if (!(attr[tindex] & ATTR_REVERSE)) {
if (bgcolour >= 256) /* Default color */
bgcolour = -1; /* No coloring */
if (fgcolour >= 256) { /* Default colour */
if (bold_mode == BOLD_COLOURS && (fgcolour & 1) && bgcolour == -1)
attrBold = ATTR_BOLD; /* Emphasize text with bold attribute */
fgcolour = -1; /* No coloring */
}
}
/*
* Write RTF text attributes
*/
if (lastfgcolour != fgcolour) {
lastfgcolour = fgcolour;
rtflen += sprintf(&rtf[rtflen], "\\cf%d ", (fgcolour >= 0) ? palette[fgcolour] : 0);
}
if (lastbgcolour != bgcolour) {
lastbgcolour = bgcolour;
rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", (bgcolour >= 0) ? palette[bgcolour] : 0);
}
if (lastAttrBold != attrBold) {
lastAttrBold = attrBold;
rtflen += sprintf(&rtf[rtflen], "%s", attrBold ? "\\b " : "\\b0 ");
}
if (lastAttrUnder != attrUnder) {
lastAttrUnder = attrUnder;
rtflen += sprintf(&rtf[rtflen], "%s", attrUnder ? "\\ul " : "\\ulnone ");
}
}
if (unitab[tdata[tindex]] == udata[uindex]) {
multilen = 1;
before[0] = '\0';
@ -4591,12 +4749,13 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect)
uindex++;
}
strcpy(rtf + rtflen, "}");
rtflen += 2;
rtf[rtflen++] = '}'; /* Terminate RTF stream */
rtf[rtflen++] = '\0';
rtf[rtflen++] = '\0';
clipdata3 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, rtflen);
if (clipdata3 && (lock3 = GlobalLock(clipdata3)) != NULL) {
strcpy(lock3, rtf);
memcpy(lock3, rtf, rtflen);
GlobalUnlock(clipdata3);
}
sfree(rtf);