1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  This file is part of the GtkHTML library.
3  *
4  *  Copyright (C) 2000 Helix Code, Inc.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20 */
21 
22 #include <config.h>
23 #include "htmlcolor.h"
24 #include "htmlcolorset.h"
25 #include "htmlpainter.h"
26 
27 
28 
29 HTMLColorSet *
html_colorset_new(GtkWidget * w)30 html_colorset_new (GtkWidget *w)
31 {
32 	HTMLColorSet *s;
33 
34 	s = g_new0 (HTMLColorSet, 1);
35 
36 	/* these are default color settings */
37 
38 	if (w && gtk_widget_get_style_context (w)) {
39 		html_colorset_set_style (s, w);
40 	} else {
41 		s->color[HTMLLinkColor]            = html_color_new_from_rgb (0, 0, 0xffff);
42 		s->color[HTMLALinkColor]           = html_color_new_from_rgb (0, 0, 0xffff);
43 		s->color[HTMLVLinkColor]           = html_color_new_from_rgb (0xffff, 0, 0);
44 		s->color[HTMLSpellErrorColor]      = html_color_new_from_rgb (0xffff, 0, 0);
45 		s->color[HTMLBgColor]              = html_color_new_from_rgb (0xffff, 0xffff, 0xffff);
46 		s->color[HTMLHighlightColor]       = html_color_new_from_rgb (0x7fff, 0x7fff, 0xffff);
47 		s->color[HTMLHighlightTextColor]   = html_color_new ();
48 		s->color[HTMLHighlightNFColor]     = html_color_new ();
49 		s->color[HTMLHighlightTextNFColor] = html_color_new ();
50 		s->color[HTMLTextColor]            = html_color_new ();
51 		s->color[HTMLCiteColor]            = html_color_new ();
52 	}
53 
54 	return s;
55 }
56 
57 void
html_colorset_destroy(HTMLColorSet * set)58 html_colorset_destroy (HTMLColorSet *set)
59 {
60 	gint i;
61 
62 	g_return_if_fail (set != NULL);
63 
64 	for (i = 0; i < HTMLColors; i++) {
65 		if (set->color[i] != NULL)
66 			html_color_unref (set->color[i]);
67 	}
68 
69 	if (set->slaves)
70 		g_slist_free (set->slaves);
71 
72 	g_free (set);
73 }
74 
75 void
html_colorset_add_slave(HTMLColorSet * set,HTMLColorSet * slave)76 html_colorset_add_slave (HTMLColorSet *set,
77                          HTMLColorSet *slave)
78 {
79 	set->slaves = g_slist_prepend (set->slaves, slave);
80 }
81 
82 void
html_colorset_set_color(HTMLColorSet * s,GdkColor * color,HTMLColorId idx)83 html_colorset_set_color (HTMLColorSet *s,
84                          GdkColor *color,
85                          HTMLColorId idx)
86 {
87 	GSList *cur;
88 	HTMLColorSet *cs;
89 
90 	html_color_set (s->color[idx], color);
91 	s->changed[idx] = TRUE;
92 
93 	/* forward change to slaves */
94 	cur = s->slaves;
95 	while (cur) {
96 		cs  = (HTMLColorSet *) cur->data;
97 		html_colorset_set_color (cs, color, idx);
98 		cur = cur->next;
99 	}
100 }
101 
102 HTMLColor *
html_colorset_get_color(HTMLColorSet * s,HTMLColorId idx)103 html_colorset_get_color (HTMLColorSet *s,
104                          HTMLColorId idx)
105 {
106 	return s->color[idx];
107 }
108 
109 HTMLColor *
html_colorset_get_color_allocated(HTMLColorSet * s,HTMLPainter * painter,HTMLColorId idx)110 html_colorset_get_color_allocated (HTMLColorSet *s,
111                                    HTMLPainter *painter,
112                                    HTMLColorId idx)
113 {
114 	html_color_alloc (s->color[idx], painter);
115 	return s->color[idx];
116 }
117 
118 void
html_colorset_set_by(HTMLColorSet * s,HTMLColorSet * o)119 html_colorset_set_by (HTMLColorSet *s,
120                       HTMLColorSet *o)
121 {
122 	HTMLColorId i;
123 
124 	for (i = 0; i < HTMLColors; i++) {
125 		html_colorset_set_color (s, &o->color[i]->color, i);
126 		/* unset the changed flag */
127 		s->changed[i] = FALSE;
128 	}
129 }
130 
131 void
html_colorset_set_unchanged(HTMLColorSet * s,HTMLColorSet * o)132 html_colorset_set_unchanged (HTMLColorSet *s,
133                              HTMLColorSet *o)
134 {
135 	HTMLColorId i;
136 
137 	for (i = 0; i < HTMLColors; i++) {
138 		if (!s->changed[i]) {
139 			html_colorset_set_color (s, &o->color[i]->color, i);
140 			s->changed[i] = FALSE;
141 		}
142 	}
143 }
144 
145 static void
copy_to_rgba(GdkColor * in_color,GdkRGBA * out_rgba)146 copy_to_rgba (GdkColor *in_color,
147               GdkRGBA *out_rgba)
148 {
149 	g_return_if_fail (in_color != NULL);
150 	g_return_if_fail (out_rgba != NULL);
151 
152 	out_rgba->alpha = 1.0;
153 	out_rgba->red = in_color->red / 65535.0;
154 	out_rgba->green = in_color->green / 65535.0;
155 	out_rgba->blue = in_color->blue / 65535.0;
156 }
157 
158 static void
get_prop_color(GtkWidget * w,const gchar * name,const gchar * dv,gboolean silent_fallback,GdkRGBA * out_color)159 get_prop_color (GtkWidget *w,
160                 const gchar *name,
161                 const gchar *dv,
162                 gboolean silent_fallback,
163                 GdkRGBA *out_color)
164 {
165 	GdkColor *color = NULL;
166 	GtkStyleContext *style_context = gtk_widget_get_style_context (w);
167 
168 	gtk_widget_style_get (w, name, &color, NULL);
169 
170 	if (color) {
171 		copy_to_rgba (color, out_color);
172 		gdk_color_free (color);
173 		return;
174 	}
175 
176 	if (dv && gdk_rgba_parse (out_color, dv))
177 		return;
178 
179 	if (!silent_fallback)
180 		g_warning ("falling back to text color");
181 
182 	gtk_style_context_get_color (style_context, GTK_STATE_FLAG_NORMAL, out_color);
183 }
184 
185 void
html_colorset_set_style(HTMLColorSet * s,GtkWidget * w)186 html_colorset_set_style (HTMLColorSet *s,
187                          GtkWidget *w)
188 {
189 #define SET_GCOLOR(t,rgba)										\
190 	if (!s->changed[HTML ## t ## Color]) {								\
191 		GdkColor gc;										\
192 													\
193 		gc.pixel = -1;										\
194 		gc.red = rgba.red * 65535.0;								\
195 		gc.green = rgba.green * 65535.0;							\
196 		gc.blue = rgba.blue * 65535.0;								\
197 													\
198 		if (s->color[HTML ## t ## Color]) html_color_unref (s->color[HTML ## t ## Color]);	\
199 		s->color[HTML ## t ## Color] = html_color_new_from_gdk_color (&gc);			\
200 	}
201 #define SET_COLOR_STYLE(t,nm,flbk)									\
202 	if (!s->changed[HTML ## t ## Color]) {								\
203 		GdkRGBA color_rgba;									\
204 													\
205 		if (!gtk_style_context_lookup_color (style_context, nm, &color_rgba))			\
206 			gdk_rgba_parse (&color_rgba, flbk);						\
207 													\
208 		SET_GCOLOR (t, color_rgba);								\
209 	}
210 #define SET_COLOR_STYLE2(t,nm1,nm2,flbk)								\
211 	if (!s->changed[HTML ## t ## Color]) {								\
212 		GdkRGBA color_rgba;									\
213 													\
214 		if (!gtk_style_context_lookup_color (style_context, nm1, &color_rgba) &&		\
215 		    !gtk_style_context_lookup_color (style_context, nm2, &color_rgba))			\
216 			gdk_rgba_parse (&color_rgba, flbk);						\
217 													\
218 		SET_GCOLOR (t, color_rgba);								\
219 	}
220 
221 	GdkRGBA color;
222 	gboolean backdrop;
223 	GtkStyleContext *style_context = gtk_widget_get_style_context (w);
224 	GtkStateFlags state_flags;
225 
226 	state_flags = gtk_widget_get_state_flags (w);
227 	backdrop = (state_flags & GTK_STATE_FLAG_BACKDROP) != 0;
228 
229 	SET_COLOR_STYLE (Bg,   backdrop ? "theme_unfocused_base_color" : "theme_base_color",   "#ffffff");
230 	SET_COLOR_STYLE2 (Text, backdrop ? "theme_unfocused_text_color" : "theme_text_color", backdrop ? "theme_unfocused_fg_color" : "theme_fg_color", "#000000");
231 
232 	SET_COLOR_STYLE (Highlight,       backdrop ? "theme_unfocused_selected_bg_color" : "theme_selected_bg_color", "#7f7fff");
233 	SET_COLOR_STYLE (HighlightText,   backdrop ? "theme_unfocused_selected_fg_color" : "theme_selected_fg_color", "#000000");
234 	SET_COLOR_STYLE (HighlightNF,     backdrop ? "theme_unfocused_selected_bg_color" : "theme_selected_bg_color", "#afafff");
235 	SET_COLOR_STYLE (HighlightTextNF, backdrop ? "theme_unfocused_selected_fg_color" : "theme_selected_fg_color", "#000000");
236 
237 	get_prop_color (w, "link_color", "#0000ff", FALSE, &color);
238 	SET_GCOLOR (Link, color);
239 	get_prop_color (w, "alink_color", "#0000ff", FALSE, &color);
240 	SET_GCOLOR (ALink, color);
241 	get_prop_color (w, "vlink_color", "#ff0000", FALSE, &color);
242 	SET_GCOLOR (VLink, color);
243 	get_prop_color (w, "spell_error_color", "#ff0000", FALSE, &color);
244 	SET_GCOLOR (SpellError, color);
245 	get_prop_color (w, "cite_color", NULL, TRUE, &color);
246 	SET_GCOLOR (Cite, color);
247 
248 #undef SET_COLOR_STYLE
249 #undef SET_COLOR_FUNC
250 #undef SET_GCOLOR
251 }
252