r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / guicast / bctheme.C
blobbc88e6d60c26228ccaa6100e85b17b0e2c9b73e6
1 #include "bctheme.h"
2 #include "bcwindowbase.h"
3 #include "clip.h"
4 #include "language.h"
5 #include "vframe.h"
7 #include <errno.h>
8 #include <stdio.h>
9 #include <string.h>
11 BC_Theme::BC_Theme()
13         data_ptr = 0;
14         contents_ptr = 0;
15         last_image = 0;
16         last_pointer = 0;
19 BC_Theme::~BC_Theme()
21         image_sets.remove_all_objects();
24 void BC_Theme::dump()
26         printf("BC_Theme::dump 1 image_sets=%d contents=%d\n", 
27                 image_sets.total, 
28                 contents.total);
29         for(int i = 0; i < contents.total; i++)
30                 printf("    %s %p\n", contents.values[i], pointers.values[i]);
33 BC_Resources* BC_Theme::get_resources()
35         return BC_WindowBase::get_resources();
39 // These create single images for storage in the image_sets table.
40 VFrame* BC_Theme::new_image(char *title, char *path)
42         VFrame *existing_image = title[0] ? get_image(title) : 0;
43         if(existing_image) return existing_image;
45         BC_ThemeSet *result = new BC_ThemeSet(1, 0, title);
46         result->data[0] = new VFrame(get_image_data(path));
47         image_sets.append(result);
48         return result->data[0];
51 VFrame* BC_Theme::new_image(char *path)
53         return new_image("", path);
56 // These create image sets which are stored in the image_sets table.
57 VFrame** BC_Theme::new_image_set(char *title, int total, va_list *args)
59         VFrame **existing_image_set = title[0] ? get_image_set(title) : 0;
60         if(existing_image_set) return existing_image_set;
62         BC_ThemeSet *result = new BC_ThemeSet(total, 1, title);
63         image_sets.append(result);
64         for(int i = 0; i < total; i++)
65         {
66                 char *path = va_arg(*args, char*);
67                 result->data[i] = new_image(path);
68         }
69         return result->data;
72 VFrame** BC_Theme::new_image_set(char *title, int total, ...)
74         va_list list;
75         va_start(list, total);
76         VFrame **result = new_image_set(title, total, &list);
77         va_end(list);
79         return result;
82 VFrame** BC_Theme::new_image_set(int total, ...)
84         va_list list;
85         va_start(list, total);
86         VFrame **result = new_image_set("", total, &list);
87         va_end(list);
89         return result;
92 VFrame* BC_Theme::get_image(char *title)
94         for(int i = 0; i < image_sets.total; i++)
95         {
96                 if(!strcmp(image_sets.values[i]->title, title))
97                 {
98                         return image_sets.values[i]->data[0];
99                 }
100         }
104 // TODO: Need to return a default image
105         return 0;
108 VFrame** BC_Theme::get_image_set(char *title)
110         for(int i = 0; i < image_sets.total; i++)
111         {
112                 if(!strcmp(image_sets.values[i]->title, title))
113                 {
114                         return image_sets.values[i]->data;
115                 }
116         }
120 // TODO: Need to return a default image set
121         return 0;
136 VFrame** BC_Theme::new_button(char *overlay_path, 
137         char *up_path, 
138         char *hi_path, 
139         char *dn_path)
141         VFrame default_data(get_image_data(overlay_path));
142         BC_ThemeSet *result = new BC_ThemeSet(3, 1, "");
144         result->data[0] = new_image(up_path);
145         result->data[1] = new_image(hi_path);
146         result->data[2] = new_image(dn_path);
147         for(int i = 0; i < 3; i++)
148                 overlay(result->data[i], &default_data);
149         return result->data;
153 VFrame** BC_Theme::new_button(char *overlay_path, 
154         VFrame *up,
155         VFrame *hi,
156         VFrame *dn)
158         VFrame default_data(get_image_data(overlay_path));
159         BC_ThemeSet *result = new BC_ThemeSet(3, 0, "");
161         result->data[0] = new VFrame(*up);
162         result->data[1] = new VFrame(*hi);
163         result->data[2] = new VFrame(*dn);
164         for(int i = 0; i < 3; i++)
165                 overlay(result->data[i], &default_data);
166         return result->data;
170 VFrame** BC_Theme::new_toggle(char *overlay_path, 
171         char *up_path,
172         char *hi_path,
173         char *checked_path,
174         char *dn_path,
175         char *checkedhi_path)
177         VFrame default_data(get_image_data(overlay_path));
178         BC_ThemeSet *result = new BC_ThemeSet(5, 1, "");
180         result->data[0] = new_image(up_path);
181         result->data[1] = new_image(hi_path);
182         result->data[2] = new_image(checked_path);
183         result->data[3] = new_image(dn_path);
184         result->data[4] = new_image(checkedhi_path);
185         for(int i = 0; i < 5; i++)
186                 overlay(result->data[i], &default_data);
187         return result->data;
190 VFrame** BC_Theme::new_toggle(char *overlay_path, 
191         VFrame *up,
192         VFrame *hi,
193         VFrame *checked,
194         VFrame *dn,
195         VFrame *checkedhi)
197         VFrame default_data(get_image_data(overlay_path));
198         BC_ThemeSet *result = new BC_ThemeSet(5, 0, "");
200         result->data[0] = new VFrame(*up);
201         result->data[1] = new VFrame(*hi);
202         result->data[2] = new VFrame(*checked);
203         result->data[3] = new VFrame(*dn);
204         result->data[4] = new VFrame(*checkedhi);
205         for(int i = 0; i < 5; i++)
206                 overlay(result->data[i], &default_data);
207         return result->data;
209 void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2)
211         int w;
212         int h;
213         unsigned char **in_rows;
214         unsigned char **out_rows;
216         if(in_x1 < 0)
217         {
218                 w = MIN(src->get_w(), dst->get_w());
219                 h = MIN(dst->get_h(), src->get_h());
220                 in_x1 = 0;
221                 in_x2 = w;
222         }
223         else
224         {
225                 w = in_x2 - in_x1;
226                 h = MIN(dst->get_h(), src->get_h());
227         }
228         in_rows = src->get_rows();
229         out_rows = dst->get_rows();
231         switch(src->get_color_model())
232         {
233                 case BC_RGBA8888:
234                         switch(dst->get_color_model())
235                         {
236                                 case BC_RGBA8888:
237                                         for(int i = 0; i < h; i++)
238                                         {
239                                                 unsigned char *in_row = in_rows[i] + in_x1 * 4;
240                                                 unsigned char *out_row = out_rows[i];
241                                                 for(int j = 0; j < w; j++)
242                                                 {
243                                                         int opacity = in_row[3];
244                                                         int transparency = 0xff - opacity;
245                                                         out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
246                                                         out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
247                                                         out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
248                                                         out_row[3] = MAX(in_row[3], out_row[3]);
249                                                         out_row += 4;
250                                                         in_row += 4;
251                                                 }
252                                         }
253                                         break;
254                                 case BC_RGB888:
255                                         for(int i = 0; i < h; i++)
256                                         {
257                                                 unsigned char *in_row = in_rows[i] + in_x1 * 4;
258                                                 unsigned char *out_row = out_rows[i];
259                                                 for(int j = 0; j < w; j++)
260                                                 {
261                                                         int opacity = in_row[3];
262                                                         int transparency = 0xff - opacity;
263                                                         out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
264                                                         out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
265                                                         out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
266                                                         out_row += 3;
267                                                         in_row += 4;
268                                                 }
269                                         }
270                                         break;
271                         }
272                         break;
273         }
276 void BC_Theme::set_data(unsigned char *ptr)
278         contents_ptr = (char*)(ptr + sizeof(int));
279         int contents_size = *(int*)ptr - sizeof(int);
280         data_ptr = contents_ptr + contents_size;
282         for(int i = 0; i < contents_size; )
283         {
284                 used.append(0);
285                 contents.append(contents_ptr + i);
286                 while(contents_ptr[i] && i < contents_size)
287                         i++;
288                 if(i < contents_size)
289                 {
290                         i++;
291                         pointers.append((unsigned char*)data_ptr + 
292                                 *(unsigned int*)(contents_ptr + i));
293                         i += 4;
294                 }
295                 else
296                 {
297                         pointers.append((unsigned char*)data_ptr);
298                         break;
299                 }
300         }
303 unsigned char* BC_Theme::get_image_data(char *title)
305         if(!data_ptr)
306         {
307                 fprintf(stderr, "BC_Theme::get_image_data: no data set\n");
308                 return 0;
309         }
311 // Image is the same as the last one
312         if(last_image && !strcasecmp(last_image, title))
313         {
314                 return last_pointer;
315         }
316         else
317 // Search for image anew.
318         for(int i = 0; i < contents.total; i++)
319         {
320                 if(!strcasecmp(contents.values[i], title))
321                 {
322                         last_pointer = pointers.values[i];
323                         last_image = contents.values[i];
324                         used.values[i] = 1;
325                         return pointers.values[i];
326                 }
327         }
329         fprintf(stderr, _("Theme::get_image: %s not found.\n"), title);
330         return 0;
333 void BC_Theme::check_used()
335 // Can't use because some images are gotten the old fashioned way.
336 return;
337         int got_it = 0;
338         for(int i = 0; i < used.total; i++)
339         {
340                 if(!used.values[i])
341                 {
342                         if(!got_it)
343                                 printf(_("BC_Theme::check_used: Images aren't used.\n"));
344                         printf("%s ", contents.values[i]);
345                         got_it = 1;
346                 }
347         }
348         if(got_it) printf("\n");
362 BC_ThemeSet::BC_ThemeSet(int total, int is_reference, char *title)
364         this->total = total;
365         this->title = title;
366         this->is_reference = is_reference;
367         data = new VFrame*[total];
370 BC_ThemeSet::~BC_ThemeSet()
372         if(data) 
373         {
374                 if(!is_reference)
375                 {
376                         for(int i = 0; i < total; i++)
377                                 delete data[i];
378                 }
380                 delete [] data;
381         }