1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: color.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2013-2020 Eduardo Chappa
8 * Copyright 2006-2007 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include "../pith/headers.h"
20 #include "../pith/color.h"
21 #include "../pith/state.h"
22 #include "../pith/conf.h"
23 #include "../pith/filter.h"
27 color_embed(char *fg
, char *bg
)
29 static char buf
[(2 * RGBLEN
) + 5], *p
;
33 if(sizeof(buf
)-(p
-buf
) > 1){
38 sstrncpy(&p
, color_to_asciirgb(fg
), sizeof(buf
)-(p
-buf
));
42 if(sizeof(buf
)-(p
-buf
) > 1){
47 sstrncpy(&p
, color_to_asciirgb(bg
), sizeof(buf
)-(p
-buf
));
50 buf
[sizeof(buf
)-1] = '\0';
57 colorcmp(char *color1
, char *color2
)
60 return(strcmp(color_to_asciirgb(color1
), color_to_asciirgb(color2
)));
62 /* if both NULL they're the same? */
63 return(!(color1
|| color2
));
70 struct quote_colors
*next
;
75 color_a_quote(long int linenum
, char *line
, LT_INS_S
**ins
, void *is_flowed_msg
)
78 struct variable
*vars
= ps_global
->vars
;
80 struct quote_colors
*colors
= NULL
, *cp
, *next
;
81 COLOR_PAIR
*col
= NULL
;
82 int is_flowed
= is_flowed_msg
? *((int *)is_flowed_msg
) : 0;
86 while(isspace((unsigned char)*p
))
90 struct quote_colors
*c
;
93 * We have a fixed number of quote level colors (3). If there are
94 * more levels of quoting than are defined, they repeat.
96 if(VAR_QUOTE1_FORE_COLOR
&& VAR_QUOTE1_BACK_COLOR
&&
97 (col
= new_color_pair(VAR_QUOTE1_FORE_COLOR
,
98 VAR_QUOTE1_BACK_COLOR
)) &&
99 pico_is_good_colorpair(col
)){
100 c
= (struct quote_colors
*)fs_get(sizeof(*c
));
101 memset(c
, 0, sizeof(*c
));
107 if(VAR_QUOTE2_FORE_COLOR
&& VAR_QUOTE2_BACK_COLOR
&&
108 (col
= new_color_pair(VAR_QUOTE2_FORE_COLOR
,
109 VAR_QUOTE2_BACK_COLOR
)) &&
110 pico_is_good_colorpair(col
)){
111 c
= (struct quote_colors
*)fs_get(sizeof(*c
));
112 memset(c
, 0, sizeof(*c
));
118 if(VAR_QUOTE3_FORE_COLOR
&& VAR_QUOTE3_BACK_COLOR
&&
119 (col
= new_color_pair(VAR_QUOTE3_FORE_COLOR
,
120 VAR_QUOTE3_BACK_COLOR
)) &&
121 pico_is_good_colorpair(col
)){
122 c
= (struct quote_colors
*)fs_get(sizeof(*cp
));
123 memset(c
, 0, sizeof(*c
));
135 free_color_pair(&col
);
139 cp
= (cp
&& cp
->next
) ? cp
->next
: colors
;
142 ins
= gf_line_test_new_ins(ins
, p
,
143 color_embed(cp
->color
->fg
, cp
->color
->bg
),
146 countem
= (countem
== 1) ? 0 : countem
;
150 for(; isspace((unsigned char)*p
); p
++)
155 char fg
[RGBLEN
+ 1], bg
[RGBLEN
+ 1], rgbbuf
[RGBLEN
+ 1];
157 strncpy(fg
, color_to_asciirgb(VAR_NORM_FORE_COLOR
), sizeof(fg
));
158 strncpy(bg
, color_to_asciirgb(VAR_NORM_BACK_COLOR
), sizeof(bg
));
159 fg
[sizeof(fg
)-1] = '\0';
160 bg
[sizeof(bg
)-1] = '\0';
163 * Loop watching colors, and override with most recent
164 * quote color whenever the normal foreground and background
165 * colors are in force.
168 if(*p
++ == TAG_EMBED
){
172 p
+= *p
+ 1; /* skip handle key */
176 snprintf(rgbbuf
, sizeof(rgbbuf
), "%s", p
);
177 p
+= RGBLEN
; /* advance past color value */
179 if(!colorcmp(rgbbuf
, VAR_NORM_FORE_COLOR
)
180 && !colorcmp(bg
, VAR_NORM_BACK_COLOR
))
181 ins
= gf_line_test_new_ins(ins
, p
,
182 color_embed(cp
->color
->fg
,NULL
),
187 snprintf(rgbbuf
, sizeof(rgbbuf
), "%s", p
);
188 p
+= RGBLEN
; /* advance past color value */
190 if(!colorcmp(rgbbuf
, VAR_NORM_BACK_COLOR
)
191 && !colorcmp(fg
, VAR_NORM_FORE_COLOR
))
192 ins
= gf_line_test_new_ins(ins
, p
,
193 color_embed(NULL
,cp
->color
->bg
),
203 ins
= gf_line_test_new_ins(ins
, line
+ strlen(line
),
204 color_embed(VAR_NORM_FORE_COLOR
,
205 VAR_NORM_BACK_COLOR
),
207 for(cp
= colors
; cp
&& cp
->color
; cp
= next
){
208 free_color_pair(&cp
->color
);
210 fs_give((void **)&cp
);
219 free_spec_colors(SPEC_COLOR_S
**colors
)
221 if(colors
&& *colors
){
222 free_spec_colors(&(*colors
)->next
);
224 fs_give((void **)&(*colors
)->spec
);
226 fs_give((void **)&(*colors
)->fg
);
228 fs_give((void **)&(*colors
)->bg
);
230 free_pattern(&(*colors
)->val
);
232 fs_give((void **)colors
);