Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

bctheme.C

Go to the documentation of this file.
00001 #include "bctheme.h"
00002 #include "bcwindowbase.h"
00003 #include "clip.h"
00004 #include "language.h"
00005 #include "vframe.h"
00006 
00007 #include <errno.h>
00008 #include <stdio.h>
00009 #include <string.h>
00010 
00011 BC_Theme::BC_Theme()
00012 {
00013         data_ptr = 0;
00014         contents_ptr = 0;
00015         last_image = 0;
00016         last_pointer = 0;
00017 }
00018 
00019 BC_Theme::~BC_Theme()
00020 {
00021         image_sets.remove_all_objects();
00022 }
00023 
00024 void BC_Theme::dump()
00025 {
00026         printf("BC_Theme::dump 1 image_sets=%d contents=%d\n", 
00027                 image_sets.total, 
00028                 contents.total);
00029         for(int i = 0; i < contents.total; i++)
00030                 printf("    %s %p\n", contents.values[i], pointers.values[i]);
00031 }
00032 
00033 BC_Resources* BC_Theme::get_resources()
00034 {
00035         return BC_WindowBase::get_resources();
00036 }
00037 
00038 
00039 // These create single images for storage in the image_sets table.
00040 VFrame* BC_Theme::new_image(char *title, char *path)
00041 {
00042         VFrame *existing_image = title[0] ? get_image(title, 0) : 0;
00043         if(existing_image) return existing_image;
00044 
00045         BC_ThemeSet *result = new BC_ThemeSet(1, 0, title);
00046         result->data[0] = new VFrame(get_image_data(path));
00047         image_sets.append(result);
00048         return result->data[0];
00049 }
00050 
00051 VFrame* BC_Theme::new_image(char *path)
00052 {
00053         return new_image("", path);
00054 }
00055 
00056 
00057 
00058 // These create image sets which are stored in the image_sets table.
00059 VFrame** BC_Theme::new_image_set(char *title, int total, va_list *args)
00060 {
00061         VFrame **existing_image_set = title[0] ? get_image_set(title, 0) : 0;
00062         if(existing_image_set) return existing_image_set;
00063 
00064         BC_ThemeSet *result = new BC_ThemeSet(total, 1, title);
00065         image_sets.append(result);
00066         for(int i = 0; i < total; i++)
00067         {
00068                 char *path = va_arg(*args, char*);
00069                 result->data[i] = new_image(path);
00070         }
00071         return result->data;
00072 }
00073 
00074 VFrame** BC_Theme::new_image_set_images(char *title, int total, ...)
00075 {
00076         va_list list;
00077         va_start(list, total);
00078         BC_ThemeSet *existing_image_set = title[0] ? get_image_set_object(title) : 0;
00079         if(existing_image_set)
00080         {
00081                 image_sets.remove_object(existing_image_set);
00082         }
00083 
00084         BC_ThemeSet *result = new BC_ThemeSet(total, 0, title);
00085         image_sets.append(result);
00086         for(int i = 0; i < total; i++)
00087         {
00088                 result->data[i] = va_arg(list, VFrame*);
00089         }
00090         return result->data;
00091 }
00092 
00093 VFrame** BC_Theme::new_image_set(char *title, int total, ...)
00094 {
00095         va_list list;
00096         va_start(list, total);
00097         VFrame **result = new_image_set(title, total, &list);
00098         va_end(list);
00099 
00100         return result;
00101 }
00102 
00103 VFrame** BC_Theme::new_image_set(int total, ...)
00104 {
00105         va_list list;
00106         va_start(list, total);
00107         VFrame **result = new_image_set("", total, &list);
00108         va_end(list);
00109 
00110         return result;
00111 }
00112 
00113 VFrame* BC_Theme::get_image(char *title, int use_default)
00114 {
00115         for(int i = 0; i < image_sets.total; i++)
00116         {
00117                 if(!strcmp(image_sets.values[i]->title, title))
00118                 {
00119                         return image_sets.values[i]->data[0];
00120                 }
00121         }
00122 
00123 
00124 
00125 // Return the first image it can find.  This should always work.
00126         if(use_default)
00127         {
00128                 printf("BC_Theme::get_image: image \"%s\" not found.\n",
00129                         title);
00130                 if(image_sets.total)
00131                 {
00132                         return image_sets.values[0]->data[0];
00133                 }
00134         }
00135 
00136 // Give up and go to a movie.
00137         return 0;
00138 }
00139 
00140 VFrame** BC_Theme::get_image_set(char *title, int use_default)
00141 {
00142         for(int i = 0; i < image_sets.total; i++)
00143         {
00144                 if(!strcmp(image_sets.values[i]->title, title))
00145                 {
00146                         return image_sets.values[i]->data;
00147                 }
00148         }
00149 
00150 // Get the image set with the largest number of images.
00151         if(use_default)
00152         {
00153                 printf("BC_Theme::get_image_set: image set \"%s\" not found.\n",
00154                         title);
00155                 int max_total = 0;
00156                 int max_number = -1;
00157                 for(int i = 0; i < image_sets.total; i++)
00158                 {
00159                         if(image_sets.values[i]->total > max_total)
00160                         {
00161                                 max_total = image_sets.values[i]->total;
00162                                 max_number = i;
00163                         }
00164                 }
00165 
00166                 if(max_number >= 0)
00167                         return image_sets.values[max_number]->data;
00168         }
00169 
00170 // Give up and go to a movie
00171         return 0;
00172 }
00173 
00174 BC_ThemeSet* BC_Theme::get_image_set_object(char *title)
00175 {
00176         for(int i = 0; i < image_sets.total; i++)
00177         {
00178                 if(!strcmp(image_sets.values[i]->title, title))
00179                 {
00180                         return image_sets.values[i];
00181                 }
00182         }
00183         return 0;
00184 }
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 VFrame** BC_Theme::new_button(char *overlay_path, 
00197         char *up_path, 
00198         char *hi_path, 
00199         char *dn_path,
00200         char *title)
00201 {
00202         VFrame default_data(get_image_data(overlay_path));
00203         BC_ThemeSet *result = new BC_ThemeSet(3, 1, title ? title : (char*)"");
00204         if(title) image_sets.append(result);
00205 
00206         result->data[0] = new_image(up_path);
00207         result->data[1] = new_image(hi_path);
00208         result->data[2] = new_image(dn_path);
00209         for(int i = 0; i < 3; i++)
00210         {
00211                 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00212         }
00213         return result->data;
00214 }
00215 
00216 
00217 VFrame** BC_Theme::new_button4(char *overlay_path, 
00218         char *up_path, 
00219         char *hi_path, 
00220         char *dn_path,
00221         char *disabled_path,
00222         char *title)
00223 {
00224         VFrame default_data(get_image_data(overlay_path));
00225         BC_ThemeSet *result = new BC_ThemeSet(4, 1, title ? title : (char*)"");
00226         if(title) image_sets.append(result);
00227 
00228         result->data[0] = new_image(up_path);
00229         result->data[1] = new_image(hi_path);
00230         result->data[2] = new_image(dn_path);
00231         result->data[3] = new_image(disabled_path);
00232         for(int i = 0; i < 4; i++)
00233         {
00234                 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00235         }
00236         return result->data;
00237 }
00238 
00239 
00240 VFrame** BC_Theme::new_button(char *overlay_path, 
00241         VFrame *up,
00242         VFrame *hi,
00243         VFrame *dn,
00244         char *title)
00245 {
00246         VFrame default_data(get_image_data(overlay_path));
00247         BC_ThemeSet *result = new BC_ThemeSet(3, 0, title ? title : (char*)"");
00248         if(title) image_sets.append(result);
00249 
00250         result->data[0] = new VFrame(*up);
00251         result->data[1] = new VFrame(*hi);
00252         result->data[2] = new VFrame(*dn);
00253         for(int i = 0; i < 3; i++)
00254                 overlay(result->data[i], &default_data, -1, -1, (i == 2));
00255         return result->data;
00256 }
00257 
00258 
00259 VFrame** BC_Theme::new_toggle(char *overlay_path, 
00260         char *up_path,
00261         char *hi_path,
00262         char *checked_path,
00263         char *dn_path,
00264         char *checkedhi_path,
00265         char *title)
00266 {
00267         VFrame default_data(get_image_data(overlay_path));
00268         BC_ThemeSet *result = new BC_ThemeSet(5, 1, title ? title : (char*)"");
00269         if(title) image_sets.append(result);
00270 
00271         result->data[0] = new_image(up_path);
00272         result->data[1] = new_image(hi_path);
00273         result->data[2] = new_image(checked_path);
00274         result->data[3] = new_image(dn_path);
00275         result->data[4] = new_image(checkedhi_path);
00276         for(int i = 0; i < 5; i++)
00277                 overlay(result->data[i], &default_data, -1, -1, (i == 3));
00278         return result->data;
00279 }
00280 
00281 VFrame** BC_Theme::new_toggle(char *overlay_path, 
00282         VFrame *up,
00283         VFrame *hi,
00284         VFrame *checked,
00285         VFrame *dn,
00286         VFrame *checkedhi,
00287         char *title)
00288 {
00289         VFrame default_data(get_image_data(overlay_path));
00290         BC_ThemeSet *result = new BC_ThemeSet(5, 0, title ? title : (char*)"");
00291         if(title) image_sets.append(result);
00292 
00293         result->data[0] = new VFrame(*up);
00294         result->data[1] = new VFrame(*hi);
00295         result->data[2] = new VFrame(*checked);
00296         result->data[3] = new VFrame(*dn);
00297         result->data[4] = new VFrame(*checkedhi);
00298         for(int i = 0; i < 5; i++)
00299                 overlay(result->data[i], &default_data, -1, -1, (i == 3));
00300         return result->data;
00301 }
00302 
00303 void BC_Theme::overlay(VFrame *dst, VFrame *src, int in_x1, int in_x2, int shift)
00304 {
00305         int w;
00306         int h;
00307         unsigned char **in_rows;
00308         unsigned char **out_rows;
00309 
00310         if(in_x1 < 0)
00311         {
00312                 w = MIN(src->get_w(), dst->get_w());
00313                 h = MIN(dst->get_h(), src->get_h());
00314                 in_x1 = 0;
00315                 in_x2 = w;
00316         }
00317         else
00318         {
00319                 w = in_x2 - in_x1;
00320                 h = MIN(dst->get_h(), src->get_h());
00321         }
00322         in_rows = src->get_rows();
00323         out_rows = dst->get_rows();
00324 
00325         switch(src->get_color_model())
00326         {
00327                 case BC_RGBA8888:
00328                         switch(dst->get_color_model())
00329                         {
00330                                 case BC_RGBA8888:
00331                                         for(int i = shift; i < h; i++)
00332                                         {
00333                                                 unsigned char *in_row = 0;
00334                                                 unsigned char *out_row;
00335 
00336                                                 if(!shift)
00337                                                 {
00338                                                         in_row = in_rows[i] + in_x1 * 4;
00339                                                         out_row = out_rows[i];
00340                                                 }
00341                                                 else
00342                                                 {
00343                                                         in_row = in_rows[i - 1] + in_x1 * 4;
00344                                                         out_row = out_rows[i] + 4;
00345                                                 }
00346 
00347                                                 for(int j = shift; j < w; j++)
00348                                                 {
00349                                                         int opacity = in_row[3];
00350                                                         int transparency = 0xff - opacity;
00351 
00352                                                         out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
00353                                                         out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
00354                                                         out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
00355                                                         out_row[3] = MAX(in_row[3], out_row[3]);
00356                                                         out_row += 4;
00357                                                         in_row += 4;
00358                                                 }
00359                                         }
00360                                         break;
00361 
00362                                 case BC_RGB888:
00363                                         for(int i = shift; i < h; i++)
00364                                         {
00365                                                 unsigned char *in_row;
00366                                                 unsigned char *out_row = out_rows[i];
00367 
00368                                                 if(!shift)
00369                                                 {
00370                                                         in_row = in_rows[i] + in_x1 * 3;
00371                                                         out_row = out_rows[i];
00372                                                 }
00373                                                 else
00374                                                 {
00375                                                         in_row = in_rows[i - 1] + in_x1 * 3;
00376                                                         out_row = out_rows[i] + 3;
00377                                                 }
00378 
00379                                                 for(int j = shift; j < w; j++)
00380                                                 {
00381                                                         int opacity = in_row[3];
00382                                                         int transparency = 0xff - opacity;
00383                                                         out_row[0] = (in_row[0] * opacity + out_row[0] * transparency) / 0xff;
00384                                                         out_row[1] = (in_row[1] * opacity + out_row[1] * transparency) / 0xff;
00385                                                         out_row[2] = (in_row[2] * opacity + out_row[2] * transparency) / 0xff;
00386                                                         out_row += 3;
00387                                                         in_row += 4;
00388                                                 }
00389                                         }
00390                                         break;
00391                         }
00392                         break;
00393         }
00394 }
00395 
00396 void BC_Theme::set_data(unsigned char *ptr)
00397 {
00398         contents_ptr = (char*)(ptr + sizeof(int));
00399         int contents_size = *(int*)ptr - sizeof(int);
00400         data_ptr = contents_ptr + contents_size;
00401 
00402         for(int i = 0; i < contents_size; )
00403         {
00404                 used.append(0);
00405                 contents.append(contents_ptr + i);
00406                 while(contents_ptr[i] && i < contents_size)
00407                         i++;
00408                 if(i < contents_size)
00409                 {
00410                         i++;
00411                         pointers.append((unsigned char*)data_ptr + 
00412                                 *(unsigned int*)(contents_ptr + i));
00413                         i += 4;
00414                 }
00415                 else
00416                 {
00417                         pointers.append((unsigned char*)data_ptr);
00418                         break;
00419                 }
00420         }
00421 }
00422 
00423 unsigned char* BC_Theme::get_image_data(char *title)
00424 {
00425         if(!data_ptr)
00426         {
00427                 fprintf(stderr, "BC_Theme::get_image_data: no data set\n");
00428                 return 0;
00429         }
00430 
00431 // Image is the same as the last one
00432         if(last_image && !strcasecmp(last_image, title))
00433         {
00434                 return last_pointer;
00435         }
00436         else
00437 // Search for image anew.
00438         for(int i = 0; i < contents.total; i++)
00439         {
00440                 if(!strcasecmp(contents.values[i], title))
00441                 {
00442                         last_pointer = pointers.values[i];
00443                         last_image = contents.values[i];
00444                         used.values[i] = 1;
00445                         return pointers.values[i];
00446                 }
00447         }
00448 
00449         fprintf(stderr, _("Theme::get_image: %s not found.\n"), title);
00450         return 0;
00451 }
00452 
00453 void BC_Theme::check_used()
00454 {
00455 // Can't use because some images are gotten the old fashioned way.
00456 return;
00457         int got_it = 0;
00458         for(int i = 0; i < used.total; i++)
00459         {
00460                 if(!used.values[i])
00461                 {
00462                         if(!got_it)
00463                                 printf(_("BC_Theme::check_used: Images aren't used.\n"));
00464                         printf("%s ", contents.values[i]);
00465                         got_it = 1;
00466                 }
00467         }
00468         if(got_it) printf("\n");
00469 }
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 BC_ThemeSet::BC_ThemeSet(int total, int is_reference, char *title)
00483 {
00484         this->total = total;
00485         this->title = new char[strlen(title) + 1];
00486         strcpy(this->title, title);
00487         this->is_reference = is_reference;
00488         data = new VFrame*[total];
00489 }
00490 
00491 BC_ThemeSet::~BC_ThemeSet()
00492 {
00493         if(data) 
00494         {
00495                 if(!is_reference)
00496                 {
00497                         for(int i = 0; i < total; i++)
00498                                 delete data[i];
00499                 }
00500 
00501                 delete [] data;
00502         }
00503 
00504         delete [] title;
00505 }
00506 
00507 
00508 
00509 
00510 

Generated on Sun Jan 8 13:26:33 2006 for Guicast-svn by  doxygen 1.4.4