diff --git a/windows/window.c b/windows/window.c index 8faa57e9..88a29dd4 100644 --- a/windows/window.c +++ b/windows/window.c @@ -24,6 +24,7 @@ #include "storage.h" #include "win_res.h" #include "winsecur.h" +#include "tree234.h" #ifndef NO_MULTIMON #include @@ -4986,6 +4987,18 @@ void write_aclip(void *frontend, char *data, int len, int must_deselect) SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0); } +typedef struct _rgbindex { + int index; + COLORREF ref; +} rgbindex; + +int cmpCOLORREF(void *va, void *vb) +{ + COLORREF a = ((rgbindex *)va)->ref; + COLORREF b = ((rgbindex *)vb)->ref; + return (a < b) ? -1 : (a > b) ? +1 : 0; +} + /* * Note: unlike write_aclip() this will not append a nul. */ @@ -5033,12 +5046,15 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour int rtfsize = 0; int multilen, blen, alen, totallen, i; char before[16], after[4]; - int fgcolour, lastfgcolour = 0; - int bgcolour, lastbgcolour = 0; + int fgcolour, lastfgcolour = -1; + int bgcolour, lastbgcolour = -1; + COLORREF fg, lastfg = -1; + COLORREF bg, lastbg = -1; int attrBold, lastAttrBold = 0; int attrUnder, lastAttrUnder = 0; int palette[NALLCOLOURS]; int numcolours; + tree234 *rgbtree = NULL; FontSpec *font = conf_get_fontspec(conf, CONF_font); get_unitab(CP_ACP, unitab, 0); @@ -5076,7 +5092,7 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour fgcolour ++; } - if (attr[i] & ATTR_BLINK) { + if ((attr[i] & ATTR_BLINK)) { if (bgcolour < 8) /* ANSI colours */ bgcolour += 8; else if (bgcolour >= 256) /* Default colours */ @@ -5087,6 +5103,28 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour palette[bgcolour]++; } + if (truecolour) { + rgbtree = newtree234(cmpCOLORREF); + for (i = 0; i < (len-1); i++) { + if (truecolour[i].fg.enabled) { + rgbindex *rgbp = snew(rgbindex); + rgbp->ref = RGB(truecolour[i].fg.r, + truecolour[i].fg.g, + truecolour[i].fg.b); + if (add234(rgbtree, rgbp) != rgbp) + sfree(rgbp); + } + if (truecolour[i].bg.enabled) { + rgbindex *rgbp = snew(rgbindex); + rgbp->ref = RGB(truecolour[i].bg.r, + truecolour[i].bg.g, + truecolour[i].bg.b); + if (add234(rgbtree, rgbp) != rgbp) + sfree(rgbp); + } + } + } + /* * Next - Create a reduced palette */ @@ -5096,6 +5134,12 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour palette[i] = ++numcolours; } + if (rgbtree) { + rgbindex *rgbp; + for (i = 0; (rgbp = index234(rgbtree, i)) != NULL; i++) + rgbp->index = ++numcolours; + } + /* * Finally - Write the colour table */ @@ -5108,6 +5152,12 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;", defpal[i].rgbtRed, defpal[i].rgbtGreen, defpal[i].rgbtBlue); } } + if (rgbtree) { + rgbindex *rgbp; + for (i = 0; (rgbp = index234(rgbtree, i)) != NULL; i++) + rtflen += sprintf(&rtf[rtflen], "\\red%d\\green%d\\blue%d;", + GetRValue(rgbp->ref), GetGValue(rgbp->ref), GetBValue(rgbp->ref)); + } strcpy(&rtf[rtflen], "}"); rtflen ++; } @@ -5151,23 +5201,44 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour /* * Determine foreground and background colours */ - fgcolour = ((attr[tindex] & ATTR_FGMASK) >> ATTR_FGSHIFT); - bgcolour = ((attr[tindex] & ATTR_BGMASK) >> ATTR_BGSHIFT); + if (truecolour && truecolour[tindex].fg.enabled) { + fgcolour = -1; + fg = RGB(truecolour[tindex].fg.r, + truecolour[tindex].fg.g, + truecolour[tindex].fg.b); + } else { + fgcolour = ((attr[tindex] & ATTR_FGMASK) >> ATTR_FGSHIFT); + fg = -1; + } + + if (truecolour && truecolour[tindex].bg.enabled) { + bgcolour = -1; + bg = RGB(truecolour[tindex].bg.r, + truecolour[tindex].bg.g, + truecolour[tindex].bg.b); + } else { + bgcolour = ((attr[tindex] & ATTR_BGMASK) >> ATTR_BGSHIFT); + bg = -1; + } if (attr[tindex] & ATTR_REVERSE) { int tmpcolour = fgcolour; /* Swap foreground and background */ fgcolour = bgcolour; bgcolour = tmpcolour; + + COLORREF tmpref = fg; + fg = bg; + bg = tmpref; } - if (bold_colours && (attr[tindex] & ATTR_BOLD)) { + if (bold_colours && (attr[tindex] & ATTR_BOLD) && (fgcolour >= 0)) { if (fgcolour < 8) /* ANSI colours */ fgcolour += 8; else if (fgcolour >= 256) /* Default colours */ fgcolour ++; } - if (attr[tindex] & ATTR_BLINK) { + if ((attr[tindex] & ATTR_BLINK) && (bgcolour >= 0)) { if (bgcolour < 8) /* ANSI colours */ bgcolour += 8; else if (bgcolour >= 256) /* Default colours */ @@ -5206,15 +5277,33 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour /* * Write RTF text attributes */ - if (lastfgcolour != fgcolour) { - lastfgcolour = fgcolour; - rtflen += sprintf(&rtf[rtflen], "\\cf%d ", (fgcolour >= 0) ? palette[fgcolour] : 0); - } + if ((lastfgcolour != fgcolour) || (lastfg != fg)) { + lastfgcolour = fgcolour; + lastfg = fg; + if (fg == -1) + rtflen += sprintf(&rtf[rtflen], "\\cf%d ", + (fgcolour >= 0) ? palette[fgcolour] : 0); + else { + rgbindex rgb, *rgbp; + rgb.ref = fg; + if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL) + rtflen += sprintf(&rtf[rtflen], "\\cf%d ", rgbp->index); + } + } - if (lastbgcolour != bgcolour) { - lastbgcolour = bgcolour; - rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", (bgcolour >= 0) ? palette[bgcolour] : 0); - } + if ((lastbgcolour != bgcolour) || (lastbg != bg)) { + lastbgcolour = bgcolour; + lastbg = bg; + if (bg == -1) + rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", + (bgcolour >= 0) ? palette[bgcolour] : 0); + else { + rgbindex rgb, *rgbp; + rgb.ref = bg; + if ((rgbp = find234(rgbtree, &rgb, NULL)) != NULL) + rtflen += sprintf(&rtf[rtflen], "\\highlight%d ", rgbp->index); + } + } if (lastAttrBold != attrBold) { lastAttrBold = attrBold; @@ -5295,6 +5384,13 @@ void write_clip(void *frontend, wchar_t *data, int *attr, truecolour *truecolour GlobalUnlock(clipdata3); } sfree(rtf); + + if (rgbtree) { + rgbindex *rgbp; + while ((rgbp = delpos234(rgbtree, 0)) != NULL) + sfree(rgbp); + freetree234(rgbtree); + } } else clipdata3 = NULL;