Subject: Re: Colors and "reverse"

From: Stephen Casner <[email-masked]>
Date: Tue, 10 Jul 2001 18:31:37 -0700 (PDT)

Some 20 months ago, I asked the question appended at the end of this
message about the interaction of reverse color selections and index
color selections.  There was no reply.  Now I have done something
about it by changing the code myself.

In the existing pine code, the paint_index_line() function in
pine/mailindx.c itself implements the policy that index lines with
color always get the colors reversed for the "current" index line.
Instead, I added a new function pico_apply_rev_color() into
pico/pico_os.c where the status of coloration is kept, and I call that
function from paint_index_line().  The new function might be useful in
other places, too.

The new pico_apply_rev_color() function implements the following
policy:

 * Apply the appropriate reverse color transformation to the given
 * color pair and return a new color pair.  The transformation depends
 * upon several factors:
 *  - if reverse is not a color, then just swap the color pair.
 *  - if the normal background color is the same as the reverse background
 *    color (presumably with different foreground colors), and the reverse
 *    foreground color is different from both the given colors, then
 *    change the foreground color to the reverse foreground color.
 *  - if the normal foreground color is the same as the reverse foreground
 *    color (presumably with different background colors), and the reverse
 *    background color is different from both the given colors, then
 *    change the background color to the reverse background color.
 *  - otherwise, just swap the color pair.

Following the principle of least surprise, the new function has the
same behavior as the existing code when reverse color has the default
setting or when the reverse color changes both the foreground and
background colors.  But when reverse color is selected such that the
transformation from normal color is to change only the foreground
color or only the background color, this new function will apply that
same transformation to colored index lines rather than forcing the
default reverse behavior of swapping the index colors.  As a safety
measure, if that transformation would cause the foreground and
background colors to be the same (making the text disappear), then the
old behavior of just reversing the index coloring is applied.

So, this new code doesn't require any changes to the methods for
configuring colors and should minimize the probability of surprise to
users (except pleasant surprise for anyone out there who shares my
preferences).  It works both for people who use different background
index colors and who want the foreground color to change for "current"
as well as those who use different foreground index colors and want
the background color to change for "current".

Therefore, I would hope that the Pine development team might accept
this code change for incorporation into the real code base so I could
get the same behavior in PC-Pine (since users can't compile it).  I
don't know all the ins and outs of pine construction, so I may not
have done everything the way it needs to be or in all the places it
needs to be, but I did add my new code into pico/osdep/unix so it gets
properly built into pico/pico_os.c.

The 3-file, 18-code-line patch to pine 4.33 is attached.

							-- Steve

On Tue, 14 Dec 1999, Stephen Casner wrote:

> The colors in 4.21 are a nice feature, but I have not been able to
> figure out if it can do exactly what I want.  In past versions, I have
> used black text on white background for the normal text color and blue
> text on white background for the "reverse" color because I prefer that
> to actually reversing the video.
>
> The same coloration carried over to 4.21 until I set some index-line
> colors.  I wanted selected messages to change to black text on yellow
> background, as if highlighted with a marker.  However, when the cursor
> is on one of those messages, Pine ignores my "reverse" color setting
> and inverts that line (yellow text on black background).  What I
> wanted was blue text on yellow background.
>
> Is there a way to configure the behavior I want?  Perhaps what's
> needed is a way to specify "transparent" for the background on the
> "reverse" color as an indication that just the foreground color should
> be substituted.
> 							-- Steve
*** pine/mailindx.c.~1~	Fri Jul  6 20:07:17 2001
--- pine/mailindx.c	Mon Jul  9 13:20:55 2001
***************
*** 1392,1404 ****
  
  	    if(cur){
  		/*
! 		 * If the current line has a linecolor, we're going to use
! 		 * the reverse of that to show it is current.
  		 */
  		if(uc && h->linecolor.fg[0] && h->linecolor.bg[0] &&
  		   pico_is_good_colorpair(&h->linecolor)){
! 		    base_color = new_color_pair(h->linecolor.bg,
! 						h->linecolor.fg); /* reverse */
  		    (void)pico_set_colorp(base_color, PSC_NONE);
  		}
  		else{
--- 1392,1403 ----
  
  	    if(cur){
  		/*
! 		 * If the current line has a linecolor, apply the
! 		 * appropriate reverse transformation to show it is current.
  		 */
  		if(uc && h->linecolor.fg[0] && h->linecolor.bg[0] &&
  		   pico_is_good_colorpair(&h->linecolor)){
! 		    base_color = pico_apply_rev_color(&h->linecolor);
  		    (void)pico_set_colorp(base_color, PSC_NONE);
  		}
  		else{
*** pico/efunc.h.~1~	Thu Dec 28 15:21:13 2000
--- pico/efunc.h	Mon Jul  9 13:28:06 2001
***************
*** 250,255 ****
--- 250,256 ----
  extern  COLOR_PAIR *new_color_pair PROTO((char *, char *));
  extern	COLOR_PAIR *pico_get_cur_color PROTO((void));
  extern	COLOR_PAIR *pico_get_rev_color PROTO((void));
+ extern	COLOR_PAIR *pico_apply_rev_color PROTO((COLOR_PAIR *));
  extern	void free_color_pair PROTO((COLOR_PAIR **));
  extern	void pico_nfcolor PROTO((char *));
  extern	void pico_nbcolor PROTO((char *));
*** pico/osdep/unix.~1~	Tue Jan 30 09:17:00 2001
--- pico/osdep/unix	Mon Jul  9 14:44:31 2001
***************
*** 1335,1340 ****
--- 1335,1374 ----
  }
  
  /*
+  * Apply the appropriate reverse color transformation to the given
+  * color pair and return a new color pair.  The transformation depends
+  * upon several factors:
+  *  - if reverse is not a color, then just swap the color pair.
+  *  - if the normal background color is the same as the reverse background
+  *    color (presumably with different foreground colors), and the reverse
+  *    foreground color is different from both the given colors, then
+  *    change the foreground color to the reverse foreground color.
+  *  - if the normal foreground color is the same as the reverse foreground
+  *    color (presumably with different background colors), and the reverse
+  *    background color is different from both the given colors, then
+  *    change the background color to the reverse background color.
+  *  - otherwise, just swap the color pair.
+  *
+  * NOTE: Do free this!
+  */
+ COLOR_PAIR *
+ pico_apply_rev_color(cp)
+     COLOR_PAIR *cp;
+ {
+     COLOR_PAIR *rc = pico_get_rev_color();
+ 
+     if(_nfcolor && _nbcolor && rc) {
+ 	if (!strcmp(_nbcolor, rc->bg) && strcmp(rc->fg, cp->bg) &&
+ 	    strcmp(rc->fg, cp->fg))
+ 	  return(new_color_pair(rc->fg, cp->bg));
+ 	if (!strcmp(_nfcolor, rc->fg) && strcmp(rc->bg, cp->fg) &&
+ 	    strcmp(rc->bg, cp->bg))
+ 	  return(new_color_pair(cp->fg, rc->bg));
+     }
+     return(new_color_pair(cp->bg, cp->fg)); /* reverse */
+ }
+ 
+ /*
   * Just like pico_set_color except it doesn't set the color, it just
   * returns the value. Assumes def of PSC_NONE, since otherwise we always
   * succeed and don't need to call this.