2 #include "bcwindowbase.h"
12 #define _(String) gettext(String)
13 #define gettext_noop(String) String
14 #define N_(String) gettext_noop (String)
18 char *path_env = getenv("PATH");
19 char default_path[BCTEXTLEN];
20 char *path_ptr = path_env;
22 // Get location of executable
23 FILE *fd = fopen("/proc/self/cmdline", "r");
26 perror(_("BC_Theme::BC_Theme: can't open /proc/self/cmdline.\n"));
31 fread(default_path, 1, BCTEXTLEN, fd);
32 strcpy(path, default_path);
40 fd = fopen(path, "r");
45 // Get next entry out of path_env
62 *new_ptr++ = *path_ptr++;
66 if(new_ptr - path > 0 && *(new_ptr - 1) != '/')
71 strcat(path, default_path);
88 for(int i = 0; i < image_sets.total; i++)
89 delete image_sets.values[i];
90 for(int i = 0; i < images.total; i++)
91 delete images.values[i];
92 if(data_buffer) delete [] data_buffer;
93 if(contents_buffer) delete [] contents_buffer;
98 printf("BC_Theme::dump 1 images=%d sets=%d path=%s contents=%d\n",
103 for(int i = 0; i < contents.total; i++)
104 printf(" %s %x\n", contents.values[i], offsets.values[i]);
107 BC_Resources* BC_Theme::get_resources()
109 return BC_WindowBase::get_resources();
112 // These create image sets which are stored in the caches.
113 VFrame** BC_Theme::new_image_set(int total, ...)
116 BC_ThemeSet *result = new BC_ThemeSet(total);
117 image_sets.append(result);
120 va_start(list, total);
121 for(int i = 0; i < total; i++)
123 char *path = va_arg(list, char*);
124 result->data[i] = new_image(path);
131 VFrame** BC_Theme::new_button(char *overlay_path,
136 VFrame default_data(get_image_data(overlay_path));
137 BC_ThemeSet *result = new BC_ThemeSet(3);
139 result->data[0] = new_image(up_path);
140 result->data[1] = new_image(hi_path);
141 result->data[2] = new_image(dn_path);
142 for(int i = 0; i < 3; i++)
143 overlay(result->data[i], &default_data);
148 VFrame** BC_Theme::new_button(char *overlay_path,
153 VFrame default_data(get_image_data(overlay_path));
154 BC_ThemeSet *result = new BC_ThemeSet(3);
156 result->data[0] = new VFrame(*up);
157 result->data[1] = new VFrame(*hi);
158 result->data[2] = new VFrame(*dn);
159 for(int i = 0; i < 3; i++)
160 overlay(result->data[i], &default_data);
165 VFrame** BC_Theme::new_toggle(char *overlay_path,
170 char *checkedhi_path)
172 VFrame default_data(get_image_data(overlay_path));
173 BC_ThemeSet *result = new BC_ThemeSet(5);
175 result->data[0] = new_image(up_path);
176 result->data[1] = new_image(hi_path);
177 result->data[2] = new_image(checked_path);
178 result->data[3] = new_image(dn_path);
179 result->data[4] = new_image(checkedhi_path);
180 for(int i = 0; i < 5; i++)
181 overlay(result->data[i], &default_data);
185 VFrame** BC_Theme::new_toggle(char *overlay_path,
192 VFrame default_data(get_image_data(overlay_path));
193 BC_ThemeSet *result = new BC_ThemeSet(5);
195 result->data[0] = new VFrame(*up);
196 result->data[1] = new VFrame(*hi);
197 result->data[2] = new VFrame(*checked);
198 result->data[3] = new VFrame(*dn);
199 result->data[4] = new VFrame(*checkedhi);
200 for(int i = 0; i < 5; i++)
201 overlay(result->data[i], &default_data);
204 void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2)
208 unsigned char **in_rows;
209 unsigned char **out_rows;
213 w = MIN(src->get_w(), dst->get_w());
214 h = MIN(dst->get_h(), src->get_h());
221 h = MIN(dst->get_h(), src->get_h());
223 in_rows = src->get_rows();
224 out_rows = dst->get_rows();
226 switch(src->get_color_model())
229 switch(dst->get_color_model())
232 for(int i = 0; i < h; i++)
234 unsigned char *in_row = in_rows[i] + in_x1 * 4;
235 unsigned char *out_row = out_rows[i];
236 for(int j = 0; j < w; j++)
238 int opacity = in_row[3];
239 int transparency = 0xff - opacity;
240 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
241 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
242 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
243 out_row[3] = MAX(in_row[3], out_row[3]);
250 for(int i = 0; i < h; i++)
252 unsigned char *in_row = in_rows[i] + in_x1 * 4;
253 unsigned char *out_row = out_rows[i];
254 for(int j = 0; j < w; j++)
256 int opacity = in_row[3];
257 int transparency = 0xff - opacity;
258 out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
259 out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
260 out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
271 VFrame* BC_Theme::new_image(char *title)
273 VFrame *result = new VFrame(get_image_data(title));
274 images.append(result);
278 void BC_Theme::set_path(char *path)
280 strcpy(this->path, path);
283 unsigned char* BC_Theme::get_image_data(char *title)
288 FILE *fd = fopen(path, "r");
292 fprintf(stderr, _("Theme::get_image: %s when opening %s\n"), strerror(errno), path);
294 int data_offset, contents_offset;
299 fseek(fd, -8, SEEK_END);
300 total_bytes = ftell(fd);
301 fread(&data_offset, 1, 4, fd);
302 fread(&contents_offset, 1, 4, fd);
305 fseek(fd, data_offset, SEEK_SET);
306 data_size = contents_offset - data_offset;
307 data_buffer = new char[data_size];
308 fread(data_buffer, 1, data_size, fd);
310 fseek(fd, contents_offset, SEEK_SET);
311 contents_size = total_bytes - contents_offset;
312 contents_buffer = new char[contents_size];
313 fread(contents_buffer, 1, contents_size, fd);
315 char *start_of_title = contents_buffer;
316 for(int i = 0; i < contents_size; )
318 if(contents_buffer[i] == 0)
320 contents.append(start_of_title);
322 offsets.append(*(int*)(contents_buffer + i));
324 start_of_title = contents_buffer + i;
333 // Image is the same as the last one
334 if(last_image && !strcasecmp(last_image, title))
336 return (unsigned char*)(data_buffer + last_offset);
339 // Search for image anew.
340 for(int i = 0; i < contents.total; i++)
342 if(!strcasecmp(contents.values[i], title))
344 last_offset = offsets.values[i];
345 last_image = contents.values[i];
347 return (unsigned char*)(data_buffer + offsets.values[i]);
351 fprintf(stderr, _("Theme::get_image: %s not found.\n"), title);
355 void BC_Theme::check_used()
357 // Can't use because some images are gotten the old fashioned way.
360 for(int i = 0; i < used.total; i++)
365 printf(_("BC_Theme::check_used: Images aren't used.\n"));
366 printf("%s ", contents.values[i]);
370 if(got_it) printf("\n");
384 BC_ThemeSet::BC_ThemeSet(int total)
386 data = new VFrame*[total];
389 BC_ThemeSet::~BC_ThemeSet()
391 if(data) delete [] data;